语境正则表达式

时间:2011-03-18 01:12:25

标签: regex

我有一个逗号分隔的单词列表,我想删除逗号并用空格替换:

elements-(a,b,c,d)

变为:

elements-(a b c d)

问题是当且仅当该列表在特定上下文中时,如何使用正则表达式来执行此操作,例如:只有元素前缀 - ():

以下内容:

There are a number of elements-(a,b,c,d) and a number of other elements-(e,f,g,h)

应该成为:

There are a number of elements-(a b c d) and a number of other elements-(e f g h)

使用正则表达式执行此操作的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

对于上下文正则表达式,您可以使用zero-width look-around assertions。查找断言用于断言必须为了匹配成功才能生成某些内容,但它们不会消耗任何字符(因此“零宽度”)。

在您的情况下,您希望使用正面后视和前瞻断言。在C#中,您可以执行以下操作:

    static string Replace(string text)
    {
        return Regex.Replace(
            text,
            @"(?<=elements\-\((\w+,)*)(\w+),(?=(\w+,)*\w+\))",
            "$2 "
        );
    }

这里的模式有三个基本部分(按顺序):

  1. (?<=elements\-\((\w+,)*) - 这是积极的后视断言。它表示只有前面有文本elements-(和零或多个逗号分隔的字符串时,模式才会匹配。
  2. (\w+), - 这是实际匹配。这是正在被替换的文本。
  3. (?=(\w+,)*\w+\)) - 这是积极的前瞻性断言。它表示只有在后面跟着一个或多个以逗号分隔的字符串时,模式才会匹配。
  4. 在C#中,为了匹配内部以逗号分隔的内容,您可以选择执行以下操作:

        static string Replace(string text)
        {
            return Regex.Replace(
                text,
                @"(?<=elements\-)\(((\w+,)+\w+)\)",
                m => string.Format("({0})", m.Groups[1].Value.Replace(',', ' '))
            );
        }
    

    积极前瞻断言的基本方法仍然是相同的。

    示例输出:

    "(x,y,z) elements-(a,b) (m,m,m) elements-(c,d,e,f,g,h)"

    ... ...变为

    "(x,y,z) elements-(a b) (m,m,m) elements-(c d e f g h)"