所以我有这个正则表达式:
/'((?:[^\\']|\\.)*)'/
它应该匹配单引号字符串,而忽略内部的转义单引号\'
works here,但是当executed with PHP时,我得到不同的结果。为什么会这样?
答案 0 :(得分:3)
使用负向后看可能会更容易。还要注意,您需要两次转义斜线-一次告诉PHP您想要一个文字反斜杠,然后再次告诉正则表达式引擎您想要一个文字反斜杠。
还请注意,您的捕获表达式(.*
是贪婪的-它将捕获'
个字符之间的所有内容,包括其他'
个字符,无论是否已转义。如果您希望它在第一个未转义的'
之后停止,请改用.*?
。我在下面的示例中使用了非贪婪版本。
<?php
$test = "This is a 'test \' string' for regex selection";
$pattern = "/(?<!\\\\)'(.*?)(?<!\\\\)'/";
echo "Test data: $test\n";
echo "Pattern: $pattern\n";
if (preg_match($pattern, $test, $matches)) {
echo "Matches:\n";
var_dump($matches);
}
答案 1 :(得分:3)
这有点难逃。尽管事实上已经有一个可接受的答案,但原始模式实际上更好。为什么?它允许使用
展开Jeffery Friedl在“精通正则表达式”:"([^\\"]*(?:\\.[^\\"]*)*)"
(适用于单引号)中描述的循环技术
展开循环(使用双引号)
" # the start delimiter
([^\\"]* # anything but the end of the string or the escape char
(?:\\. # the escape char preceeding an escaped char (any char)
[^\\"]* # anything but the end of the string or the escape char
)*) # repeat
" # the end delimiter
这不能解决逃跑的地狱,但您也已在这里被覆盖:
$re = '/\'([^\\\\\']*(?:\\\\.[^\\\\\']*)*)\'/';
$str = '\'foo\', \'can\\\'t\', \'bar\'
\'foo\', \' \\\'cannott\\\'\\\\\', \'bar\'
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);