正则表达式适用于Javascript但不适用于PHP preg_match

iss*_*s42 2 php regex

正则表达式:

/([^]+):([^\\r\\n]+)/
Run Code Online (Sandbox Code Playgroud)

串:

f1:aaa\r\nf2:bbb\r\nf3:ccc\r\nf4:ddd
Run Code Online (Sandbox Code Playgroud)

根据regexpal.com,这将给我想要的设置:f1 & aaa, f2 & bbb, f3 & ccc等.但使用http://www.functions-online.com/preg_match.html我只看到[0] => "f1" and [1] => "f1"

任何人都可以说明我应该这样做吗?

Cas*_*yte 5

javascript的一些实现允许[]和分别[^]"无字符""任何字符".但请记住,这是javascript正则表达式的特殊之处.(如果您对该主题感兴趣,可以查看这篇文章.)

换句话说,[^]是一个快捷方式,[\s\S]因为javascript没有dotall单行模式,其中点可以匹配换行符.

因此,为了获得在PHP相同的结果,你必须更换[^]通过.与单线修饰符(默认情况下,除了换行符匹配任何字符)s结束分隔符之后或(?s)之前,.允许换行了.示例:/.+/s/(?s).+/

但对于您的特定情况,这种模式似乎更合适:

preg_match_all('~((?>[^rn\\\:]++|(?<!\\\)[rn])+):([^\\\]++)~', $subject, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
    echo $match[1].' '.$match[2].'<br/>';
}
Run Code Online (Sandbox Code Playgroud)

模式说明:

~                    # pattern delimiter
(                    # open the first capturing group
    (?>              # open an atomic group
        [^rn\\\:]++  # all characters that are not "r", "n", "\" or ":"
      |              # OR
        (?<!\\\)[rn] # "r" or "n" not preceded by "\"
    )+               # close the atomic group and repeat one or more times
)                    # close the first capturing group
:
(                    # open the second capturing group
    [^\\\]++         # all characters except "\" one or more times
)                    # close the second capturing group
~
Run Code Online (Sandbox Code Playgroud)

注意事项:

如果要\在由单引号括起的字符串中表示(反斜杠),则必须使用双转义:\\\

这种模式的原理是使用负字符类和否定断言,换句话说,它查找所需的子字符串不能是什么.

上述模式使用原子组(?>...)和占有量词++来代替非捕获组(?:...)和简单量词+.它是相同的,除了正则表达式引擎在原子组和占有量量化器失败时无法返回测试其他方式,因为它不记录回溯位置.您可以通过这种功能赢得性能.