问题描述
我想找一个没有的错误NCR并补救,unicode是4或5个十进制数字,我写了这个PHP语句:
function repl0($m) {
return '&#'.$m[0];
}
$s = "This is a good 23200; sample ship";
echo "input1= ".htmlentities($s)."<br>";
$out1=preg_replace_callback('/(?<!#)(\d{4,5};)/','repl0',$s);
echo 'output1 = '.htmlentities($out1).'<br>';
输出为:
input1= This is a good 23200; sample ship
output1 = This is a good 2ಀ sample ship
根据输出消息,匹配只发生一次。 我想要的是匹配 '23200;'而不是'3200;'。 默认应该是贪婪模式,我认为它会捕获 5 位数字而不是 4 位数字 我在这里误解了“贪婪”吗?我怎样才能得到我想要的?
解决方法
(?<!#)(\d{4,5};)
模式匹配如下:
-
(?<!#)
- 匹配前面没有紧跟#
的位置
-
(\d{4,5};)
- 然后尝试匹配并使用四位或五位数字以及紧跟在这些数字之后的;
字符。
所以,如果你有 #32000;
字符串输入,3
不能作为匹配的起始字符,因为它前面有 #
,但 2
可以,因为它前面没有 #
并且有五位带有 ;
的数字用于匹配模式。
这里您需要的是通过向后视添加一个数字来遏制左侧的匹配,
(?<![#\d])(\d{4,5};)
使用此技巧,您可以确保匹配项不能紧跟在 #
或数字之前。
你说你最终使用了 (?<!#)(?<!\d)\d{4,5};
,这个模式在功能上等同于上面的模式,因为后视,就像所有的环视一样,“站稳脚跟”,即当环视模式是时,正则表达式索引不会移动匹配。因此,对数字或 #
字符的检查发生在字符串中的相同位置。