Regex 正则表达式匹配“;全字;返回异常

Regex 正则表达式匹配“;全字;返回异常,regex,vb.net,validation,Regex,Vb.net,Validation,我试图通过正则表达式验证如下 If Regex.IsMatch(Output, "\b" & "Serial)" & "\b") Then 'do something end if 但我有一个例外 parsing "\bSerial)\b" - Too many )'s. 我确实理解这个错误,但是我应该如何修改正则表达式呢 更新。动态生成“串行”一词。这意味着至少对我来说,我还可以为另一个字符获得另一个异常。假设这是VB.Net,您需要转义): 在.Net正则表达式中,括号是

我试图通过正则表达式验证如下

If Regex.IsMatch(Output, "\b" & "Serial)" & "\b") Then
'do something
end if
但我有一个例外

parsing "\bSerial)\b" - Too many )'s.
我确实理解这个错误,但是我应该如何修改正则表达式呢


更新。动态生成“串行”一词。这意味着至少对我来说,我还可以为另一个字符获得另一个异常。

假设这是VB.Net,您需要转义

在.Net正则表达式中,括号是分组字符


如您所说,如果单词“Serial”是动态生成的,则在将其传递给RE引擎之前,您必须对其进行修改:

If Regex.IsMatch(Output, "\b" & Regex.Escape("Serial)") & "\b") Then
    'do something
End If

正如另一位回答者所说,这与
“Serial)xyz”
(例如)不匹配,因为
和空格之间没有
\b
\b
只存在于
\w
\w
字符之间,而且
和空格都是
\w

你可能不得不求助于一个丑陋的黑客,比如:

If Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "\s") _
Or Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "$") _
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "\s") _
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "$") _
Then
    'do something
End If
我想也许你可以匹配一个由(
^
$
)和
\s
组成的字符类,大致如下:

If Regex.IsMatch(Output, "[\s^]" & Regex.Escape("Serial)") & "[\s$]") Then
    'do something
End If
但基于regex测试仪,这似乎不起作用,因此您可能必须选择丑陋的hack版本,或者您可以将它们组合成一个单一的regex,如中所示:

var input = "Serial)"
var escaped = Regex.Escape (input)
var regex = "\s" & escaped & "\s|^" & escaped & "$|\s" & escaped & "$|^" & escaped & "\s"
If Regex.IsMatch(Output, regex) Then
    'do something
End If

我想你需要的可能是

\bSerial\)\b

(即“\b”和“Serial”&“\b”)

您应该使用以下方法来转义输入:


你需要避开括号。就是,)有) 因此,最后一个字符串应该类似于\b序列)\b

如果内容是动态生成的,则搜索“(“and”)”并将其替换为“(“and”)”的适当转义字符(仅替换字符串!),或者使用Regex.escape()转义这些字符


Paxdiablo和tanascius的回答正确地解释了正则表达式无法编译的原因

但是:

即使在转义括号后,您也需要小心正则表达式:
\b
仅在单词边界处匹配(单词由
\w
快捷方式的字符-字母、数字和下划线构成),而不是像括号一样的标点符号后。在您的情况下,正则表达式在类似
foo Serial)bar的字符串中不匹配。它将在
foo-Serial)条
中匹配,但这只是因为
\b
之前匹配。同样,它将不匹配字符串
Serial)

因此,简单地用
\b
s包围一个字符串并不总是能达到您期望的效果

编辑:如果,根据你下面的评论,在下面的列表中

foo Serial) bar
foo (Serial) bar
foo Serial). bar
foo Serial))))))
foo Serial)
…只有第一个和第五个应该匹配,我推断规则是只匹配前面/后面有空格或字符串开头/结尾的整个单词

在这种情况下,使用

If Regex.IsMatch(Output, "(?<=^|\s)" & Regex.Escape("Serial)") & "(?=\s|$)") Then
…但这也将与第二个示例相匹配。小心选择你的武器:)


(解释:
(?为了澄清,不同风格的regexp以不同的方式使用分组,posix regexp使用
\(
\\)
进行分组,perl regexp只使用
并使用
\(
\\)
表示文字括号。我想我必须编辑这个问题。会生成“序列号”一词dynamically@strakastroukas,如果是任意字符串,则正则表达式具有转义基本符号的功能-请参阅更新中的链接。@Pax,如果我使用Regex.escape,且输出包含“Serial”isMatch返回False@paxdiablo:我想你是想让你的更新有
Regex.Escape(“Serial”)
,对吧?我选择第一个,第五个!谢谢蒂姆!
foo Serial) bar
foo (Serial) bar
foo Serial). bar
foo Serial))))))
foo Serial)
If Regex.IsMatch(Output, "(?<=^|\s)" & Regex.Escape("Serial)") & "(?=\s|$)") Then
If Regex.IsMatch(Output, "(?<=^|\b|\s)" & Regex.Escape("Serial)") & "(?=\s|\b|$)") Then