.*?id="number"[^>]*?>([^<]+?).*
这真的是您使用的正则表达式吗?我问的原因是因为([^<]+?) 总是会匹配一个字符,就好像你写了([^<]) 一样。 + 量词必须至少匹配一次,但由于它不情愿,它会立即移交给下一部分 - .* - 这总是成功的。删除.* 并切换到find() 或lookingAt() 也不会改变这种行为(尽管获得相同结果可能会更快一些)。如果你想匹配所有文本直到下一个尖括号,你应该去掉问号:([^<]+)。
[^>]*?> 也没有多大意义。在匹配括号之前,您必须消耗尽可能多的非括号,那么使该量词不情愿的意义何在?事实上,让它变得贪婪也没有意义。如果[^>]* 尽可能匹配并且下一个字符不是'>',那么你知道回溯不会有任何好处。如果您的正则表达式支持它们,您不妨使用所有格量词 - [^>]*+> - 或原子组 - (?>[^>]*+)>。
第一个量化部分 - .*? - 是唯一正确使用的部分(如果不是最佳使用)。将其放在正则表达式的开头模拟find() 在您使用lookingAt() 或(末尾带有.*)matches() 时的行为。但是,正如您所发现的,将其关闭并使用 find() 会更有效。
不情愿的量词非常方便,但最近似乎它们曝光过度了。随着频率的增加,我看到人们给出“使用不情愿的量词”的建议,没有任何解释或限定——这只是另一个灵丹妙药。我相信这个问题中的正则表达式就是结果。三个不情愿的量词,一个应该是贪婪的,一个应该是所有格的,另一个根本不应该存在。
编辑:这里有一个例子来说明我在说什么,并解决斯蒂芬 C 的评论。给定这个字符串:
<div id="number" class="whatever">abc123</div>
...正则表达式的动态部分匹配如下:
.*? => '<div '
[^>]*? => ' class="whatever"'
([^<]+?) => 'a'
.* => 'bc123</div>'
将所有不情愿的量词更改为贪婪不会改变整体匹配(整个字符串),也不会改变前两个动态部分匹配的内容。但最后两个被重新分配:
([^<]+) => 'abc123'
.* => '</div>'
查看原始的正则表达式,我认为这一定是想要的结果;如果不捕获整个内容'abc123',为什么还要在捕获组中使用如此复杂的子表达式?这就是让我相信不情愿的量词被盲目使用的原因。
另一件事:回顾线程,我看到 OP 实际上并没有说他在切换到 find() 时从正则表达式的前面删除了 .*?方法。 @Ben,如果您还没有这样做,那么您应该这样做;现在只是放慢速度。这会让你得到这个正则表达式:
id="number"[^>]*+>([^<]+)
我也不希望任何人认为我在质疑公认的答案。我只是对过度使用/不当使用不情愿的量词感到不满。