删除string中的分隔符之间的文本(使用正则expression式?)
考虑要求find匹配的一组字符,并删除它们之间的任何字符, 以及那些字符/分隔符。
以下是一组分隔符:
[] square brackets () parentheses "" double quotes '' single quotes
这里有一些应该匹配的string的例子:
Given: Results In: ------------------------------------------- Hello "some" World Hello World Give [Me Some] Purple Give Purple Have Fifteen (Lunch Today) Have Fifteen Have 'a good'day Have day
以及一些不应该匹配的string示例:
Does Not Match: ------------------ Hello "world Brown]co[w Cheese'factory
如果给定的string不包含一组匹配的分隔符,则不会修改。 inputstring可能有许多匹配的分隔符对。 如果一组2个分隔符重叠(即he[llo "worl]d"
)),那么这将是一个我们可以忽略的边界情况。
algorithm看起来像这样:
string myInput = "Give [Me Some] Purple (And More) Elephants"; string pattern; //some pattern string output = Regex.Replace(myInput, pattern, string.Empty);
问题:如何用C#实现这一点? 我倾向于一个正则expression式。
奖金:有没有简单的方法来匹配那些常量或者某种列表中的开始和结束分隔符? 如果业务分析师想出新的分隔符,我所寻找的解决scheme将很容易更改分隔符。
简单的正则expression式是:
string input = "Give [Me Some] Purple (And More) Elephants"; string regex = "(\\[.*\\])|(\".*\")|('.*')|(\\(.*\\))"; string output = Regex.Replace(input, regex, "");
至于做一个自定义的方式,你要build立的正则expression式,你只需要build立的部分:
('.*') // example of the single quote check
然后每个单独的正则expression式部分连接OR(正则expression式),如我原来的例子。 一旦你有你的正则expression式stringbuild立只运行一次。 关键是要得到一个单一的检查正则expression式,因为在一个项目上执行许多正则expression式匹配,然后遍历很多项目可能会看到显着的性能下降。
在我的第一个例子中,将取代以下行:
string input = "Give [Me Some] Purple (And More) Elephants"; string regex = "Your built up regex here"; string sOutput = Regex.Replace(input, regex, "");
我相信有人会张贴一个很酷的linqexpression式来build立正则expression式基于一个分隔符对象数组来匹配或什么的。
一个简单的方法是做到这一点:
string RemoveBetween(string s, char begin, char end) { Regex regex = new Regex(string.Format("\\{0}.*?\\{1}", begin, end)); return regex.Replace(s, string.Empty); } string s = "Give [Me Some] Purple (And More) \\Elephants/ and .hats^"; s = RemoveBetween(s, '(', ')'); s = RemoveBetween(s, '[', ']'); s = RemoveBetween(s, '\\', '/'); s = RemoveBetween(s, '.', '^');
将return语句更改为以下内容将避免重复的空格:
return new Regex(" +").Replace(regex.Replace(s, string.Empty), " ");
最终的结果是:
"Give Purple and "
Disclamer :一个正则expression式可能会比这更快。
我必须添加一句老话:“你有一个问题,你想用正则expression式,现在你有两个问题。”
我已经想出了一个快速的正则expression式,希望能帮助你在你正在寻找的方向:
[.]*(\(|\[|\"|').*(\]|\)|\"|')[.]*
圆括号,括号,双引号将被转义,而单引号可以单独留下。
为了将上面的expression式转换成英文,我允许之前和之后的任何数字的字符匹配expression式在匹配的分隔符之间。
开放的分隔符短语是(\(|\[|\"|')
它有一个匹配的closures短语。为了使这个在将来可扩展一点,你可以删除实际的分隔符并将它们包含在configuration文件,数据库或者你可以select的地方。
基于Bryan Menard的正则expression式 ,我做了一个扩展方法,它也可以用于嵌套replace,如“[Test 1 [[Test2] Test3]] Hello World”:
/// <summary> /// Method used to remove the characters betweeen certain letters in a string. /// </summary> /// <param name="rawString"></param> /// <param name="enter"></param> /// <param name="exit"></param> /// <returns></returns> public static string RemoveFragmentsBetween(this string rawString, char enter, char exit) { if (rawString.Contains(enter) && rawString.Contains(exit)) { int substringStartIndex = rawString.IndexOf(enter) + 1; int substringLength = rawString.LastIndexOf(exit) - substringStartIndex; if (substringLength > 0 && substringStartIndex > 0) { string substring = rawString.Substring(substringStartIndex, substringLength).RemoveFragmentsBetween(enter, exit); if (substring.Length != substringLength) // This would mean that letters have been removed { rawString = rawString.Remove(substringStartIndex, substringLength).Insert(substringStartIndex, substring).Trim(); } } //Source: https://stackoverflow.com/a/1359521/3407324 Regex regex = new Regex(String.Format("\\{0}.*?\\{1}", enter, exit)); return new Regex(" +").Replace(regex.Replace(rawString, string.Empty), " ").Trim(); // Removing duplicate and tailing/leading spaces } else { return rawString; } }
在build议的情况下,这个方法的用法如下所示:
string testString = "[Test 1 [[Test2] Test3]] Hello World"; testString.RemoveFragmentsBetween('[',']');
返回string“Hello World”。
使用以下正则expression式
(\{\S*\})
这个正则expression式的作用是用你想要replace的修饰词replace{word}的所有出现。
一些示例C#代码:
static readonly Regex re = new Regex(@"(\{\S*\})", RegexOptions.Compiled); /// <summary> /// Pass text and collection of key/value pairs. The text placeholders will be substituted with the collection values. /// </summary> /// <param name="text">Text that containes placeholders such as {fullname}</param> /// <param name="fields">a collection of key values pairs. Pass <code>fullname</code> and the value <code>Sarah</code>. /// DO NOT PASS keys with curly brackets <code>{}</code> in the collection.</param> /// <returns>Substituted Text</returns> public static string ReplaceMatch(this string text, StringDictionary fields) { return re.Replace(text, match => fields[match.Groups[1].Value]); }
在一个句子如
Regex Hero是一个实时{在线{ Silverlight }常规}expression式testing器。
它将只replace{ Silverlight },而不是从第一个{括号到最后一个}括号开始。