删除字符串中的分隔符之间的文本(使用正则表达式?)

时间:2009-08-31 21:03:11

标签: c# .net regex algorithm string

考虑要求找到一对匹配的字符集,并删除它们之间的任何字符,以及这些字符/分隔符。

以下是分隔符集:

 []    square brackets
 ()    parentheses
 ""    double quotes
 ''    single quotes

以下是一些应匹配的字符串示例:

 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

一些不匹配的字符串示例:

 Does Not Match:
------------------
 Hello "world
 Brown]co[w
 Cheese'factory

如果给定的字符串不包含匹配的分隔符集,则不会修改它。输入字符串可以具有许多匹配的分隔符对。如果一组2个分隔符重叠(即he[llo "worl]d"),那么这就是我们可以忽略的边缘情况。

算法看起来像这样:

string myInput = "Give [Me Some] Purple (And More) Elephants";
string pattern; //some pattern
string output = Regex.Replace(myInput, pattern, string.Empty);

问题:您如何使用C#实现这一目标?我倾向于正则表达式。

加分:是否有简单的方法可以在常量或某种列表中匹配这些开始和结束分隔符?我正在寻找的解决方案很容易改变分隔符,以防业务分析师提出新的分隔符。

5 个答案:

答案 0 :(得分:42)

简单的正则表达式将是:

string input = "Give [Me Some] Purple (And More) Elephants";
string regex = "(\\[.*\\])|(\".*\")|('.*')|(\\(.*\\))";
string output = Regex.Replace(input, regex, "");

至于你想要建立正则表达式的自定义方式,你只需要构建部分:

('.*')  // example of the single quote check

然后将每个单独的正则表达式部分与OR(正则表达式中的|)连接,如我原始示例中所示。一旦你建立了正则表达式字符串,就运行一次。关键是要将正则表达式放到一个单一的检查中,因为在一个项目上执行许多正则表达式匹配然后迭代很多项目可能会看到性能显着下降。

在我的第一个例子中,它取代了以下一行:

string input = "Give [Me Some] Purple (And More) Elephants";
string regex = "Your built up regex here";
string sOutput = Regex.Replace(input, regex, "");

我相信有人会发布一个很酷的linq表达式来构建基于分隔符对象数组的正则表达式来匹配或者什么。

答案 1 :(得分:34)

一种简单的方法是:

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 :单个正则表达式可能比这更快。

答案 2 :(得分:9)

我必须添加一句古老的格言,“你遇到了问题而且想要使用正则表达式。现在你有两个问题。”

我想出了一个快速的正则表达式,希望能帮助你朝着你正在寻找的方向发展:

[.]*(\(|\[|\"|').*(\]|\)|\"|')[.]*

括号,括号,双引号被转义,而单引号可以单独存在。

要将上面的表达式用英语,我允许在之前和之后的任何数字中使用任意数量的字符,匹配匹配分隔符之间的表达式。

开放分隔符是(\(|\[|\"|') 这有一个匹配的结束短语。为了在将来使其更具可扩展性,您可以删除实际的分隔符并将其包含在配置文件,数据库或您可以选择的任何位置。

答案 3 :(得分:3)

Bryan Menard's regular expression的基础上,我做了一个扩展方法,它也适用于嵌套替换,如“[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;
        }
    }

在建议的情况下,此方法的用法如下所示:

string testString = "[Test 1 [[Test2] Test3]] Hello World";
testString.RemoveFragmentsBetween('[',']');

返回字符串“Hello World”。

答案 4 :(得分:0)

使用以下正则表达式

(\{\S*\})

这个正则表达式的作用是将{word}的任何出现替换为你要用它替换的modifiedWord。

一些示例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 }常规}表达   测试仪。

它只会替换{ Silverlight },而不会从第一个{括号到最后一个}括号开始。