简单正则表达式的难度(匹配前缀/后缀)

时间:2008-12-28 06:46:17

标签: c# regex

我正在尝试开发一个将在C#程序中使用的正则表达式。

我最初的正则表达式是:

(?<=\()\w+(?=\))

成功匹配“(foo)” - 匹配但从输出中排除开放和关闭的parens,只生成“foo”。

但是,如果我将正则表达式修改为:

\[(?<=\()\w+(?=\))\]

我尝试匹配“[(foo)]”它无法匹配。这是令人惊讶的。我只是在我的前一个表达式前面添加和附加文字的开括号和闭括号。我很难过。我使用Expresso来开发和测试我的表达式。

提前感谢您的帮助。

Rob Cecil

2 个答案:

答案 0 :(得分:6)

你的后视是问题所在。以下是字符串的处理方式:

  1. 我们看到[在字符串中,它与正则表达式匹配。
  2. 正则表达式中的后视要求我们查看前一个字符是否为'('。这会失败,因为它是'['。
  3. 至少那就是我猜的是导致问题的原因。

    请尝试使用此正则表达式:

    (?<=\[\()\w+(?=\)\])
    

答案 1 :(得分:3)

脱离背景,很难判断,但这里的后卫可能有点矫枉过正。它们对于排除字符串很有用(比如strager的例子)以及其他一些简单RE失败的特殊情况,但我经常看到它们用于更简单的表达式更容易编写的地方,工作在更多的RE风格中并且可能更快。
在您的情况下,您可以使用自然边界编写(\b\w+\b),甚至(\w+),或者如果您想使用{{1}来区分(foo)和-foo-(例如) }。
现在,也许上下文决定了这种错综复杂的用法(或者你可能只是尝试了后视),但是了解替代方案是很好的。

现在,如果你只是好奇为什么第二个表达式不起作用:这些被称为“零宽度断言”:它们检查后面或前面的内容是否符合预期,但它们不符合消耗字符串,以便在它们之后(或者在否定之前)它们必须匹配断言。例如。如果你在积极的前瞻之后放了一些与断言不匹配的东西,你肯定RE会失败。