正则表达式非贪婪模式(懒惰模式)

37

我希望非贪心地解析TD标签。我从以下内容开始:

<TD>stuff<TD align="right">More stuff<TD align="right>Other stuff<TD>things<TD>more things

我正在使用以下内容作为我的正则表达式:

Regex.Split(tempS, @"\<TD[.\s]*?\>");

以下是记录返回结果:

""
"stuff<TD align="right">More stuff<TD align="right>Other stuff"
"things"
"more things"
为什么第一个完整结果(以“stuff”开头的结果)没有被拆分?我应该如何调整正则表达式,以便在带有参数或不带参数的TD标签的所有实例上进行拆分?

1
请参见https://dev59.com/X3I-5IYBdhLWcg3wq6do。 - Brian Rasmussen
2
.在字符类[.]中只表示一个字面上的句点,而不是'任何字符。使用[^>]*可能会更成功,但它会在属性中的>上出错(这也是为什么我们通常会使用解析器而不是正则表达式来处理HTML和XML的原因之一)。 - Wrikken
@Wrikken 这里的HTML非常静态。变化不大,我知道适用于它的正则表达式。我没有选择解析器的路线,因为这个原因。有没有办法让“.”字符表示“任何字符”,包括空格? - steventnorris
我不知道C#修饰符(在pcre中是/s)如何使点匹配所有内容。然而,[^>]*>在功能上等同于(.|\s)*?>,并且可能更容易使用正则表达式。 - Wrikken
3个回答

60

如果需要非贪婪匹配,请尝试使用 <TD.*?>


12
因为在量词符号 * 后面加上 ?,告诉正则表达式引擎在找到符合 > 表达式后停止匹配,即只取第一个匹配项。这是由于贪婪模式与非贪婪模式 * 的区别导致的。 - JustAMartin

18

来自https://regex101.com/

  • *量词——匹配0到无限次,尽可能多地匹配,需要时进行回溯(贪婪)
  • *?量词——匹配0到无限次,尽可能少地匹配,需要时扩展(惰性)

17

你需要的正则表达式是<TD[^>]*>

<     # Match opening tag
TD    # Followed by TD
[^>]* # Followed by anything not a > (zero or more)
>     # Closing tag
注意:.匹配任何字符(包括空格),因此[.\s]*?是多余和错误的,因为[.]匹配字面意义上的.,所以请使用.*?

2
默认情况下,点号不匹配换行符,但\s会匹配。 - Tommi Gustafsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接