a?\W*?b
,和一个字符串,.! ,b
在查找匹配时,我得到的是
,.! ,b
,而不是我期望的b
。为什么会这样?如何修改正则表达式以获得我需要的结果?谢谢您的帮助。
a?\W*?b
,和一个字符串,.! ,b
,.! ,b
,而不是我期望的b
。为什么会这样?如何修改正则表达式以获得我需要的结果?在这里,懒惰量词对你想要的并没有帮助。让我们看看发生了什么。
正则表达式引擎从字符串的开头开始。首先尝试匹配a
。它无法匹配,但这不是问题,因为a
是可选的。
然后,有一个懒惰的\W*?
,所以正则表达式引擎跳过它,但记住当前位置。
接下来,它尝试匹配b
。它无法匹配,所以它回溯并成功地使用\W*?
匹配,
。然后它继续尝试匹配b
(因为是懒惰量词)。它仍然不能匹配,并且回溯。这反复几次,直到最后正则表达式引擎到达b
。现在匹配完成-正则表达式引擎宣布成功。
所以正则表达式按照规定工作-只是意图不同。现在的问题是:你到底想让正则表达式做什么?
例如,如果你真正想要的是:
匹配单独的b
,除非它前面有a
和一些非单词字符,在这种情况下匹配从a
到b
的所有内容,然后使用
b|a\W*b
^([a-z].*[a-z]$|)$
。匹配以字母开头和结尾的字符串,或者匹配空字符串。如果你想要大写字母也能匹配,可以使用 RegexOptions.IgnoreCase
。如果你还想允许非ASCII字母,可以使用 \p{L}
代替 [a-z]
。 - Tim Pietzcker一个惰性表达式只从右侧惰性,即通过删除右侧字符尽可能缩短长度,但不会删除左侧字符。
为了使匹配开始更晚,您需要在它之前使用贪婪表达式来吞噬您不想匹配的字符。
或者,正如Tim所示,如果第一个字符存在,您可以仅匹配第一个字符和以下分隔符以使匹配开始更晚。
(a\W*)?b
为了更好地了解可能解决您的问题的方法,您应该包含更多示例。你的正则表达式与整个字符串匹配如下:
在你的情况下,正则表达式与整个字符串匹配,因此它将不能只找到 b (它不会找到相同部分的多个匹配)。
如果在像',。!,db'这样的字符串中搜索,它将找到 b。
a?
表示 "我想要零个或一个实例的a
" - 这得到满足,因为没有实例,接着
\W*
表示 "我想要零个或更多的非单词字符",这得到满足,因为有标点符号和空格字符,最后
b
表示 "匹配字母b
",它得到了满足。所以您整个字符串都符合正则表达式。
如果在任何人建议可能的解决方案之前您可以提供更多可能输入的示例,那将会有所帮助。
*?
... 为什么它在这里不起作用? - Thomas Levesque你的例子没有说明为什么a?
是你正则表达式的一部分,但如果要在看起来像,.! ,b
的字符串中只匹配b
,你可以使用向后查找,像这样:(?=\W*?)b
。
这个正则表达式匹配的是在一个字符之前有零到多个“非单词字符”(尽可能少)的b
如果你只想在类似a,.! ,b
的字符串中匹配a
和b
,你需要使用捕获组: (a?)\W*?(b)
,其中第一个捕获组将保存可能存在的a
,第二个捕获组保存b
把一个正则表达式称为贪婪或非贪婪是错误的。你可以在整个正则表达式中使用非贪婪量词,但它仍然会尝试在最早的机会开始匹配,就像你发现的那样。同样,只使用贪婪量词的正则表达式不能保证返回最长的匹配。例如,
Regex.Match("foo bar", @"\w+ (?:b|bar)")
......返回foo b
,因为交替选择了第一个可行的替代项,即使后面有更长的匹配结果。(请注意,我在谈论像.NET这样派生自Perl的正则表达式语法;某些语法,如awk
和egrep
,确实坚持最长可能的匹配。但是,由于这些语法没有非贪婪量词,贪婪模式不仅是默认模式,而且是唯一的模式。)
简而言之,不存在贪婪或非贪婪的正则表达式,只有贪婪或非贪婪的量词。