鉴于代码:
$my_str = '
Rollo is*
My dog*
And he\'s very*
Lovely*
';
preg_match_all('/\S+(?=\*$)/m', $my_str, $end_words);
print_r($end_words);
在PHP 7.3.2(XAMPP)中,我得到了意外的输出
Array ( [0] => Array ( ) )
而在PHPFiddle,在PHP 7.0.33上,我得到了我的预期:
Array ( [0] => Array ( [0] => is [1] => dog [2] => very [3] => Lovely ) )
任何人都可以告诉我为什么我得到这个差异,是否在7.0.33之后的REGEX行为发生了变化?
最佳答案 看起来在你所拥有的环境中,PCRE库是在没有PCRE_NEWLINE_ANY选项的情况下编译的,并且多线模式中的$仅匹配LF符号之前和.匹配任何符号,但LF.
您可以使用PCRE(* ANYCRLF)动词修复它:
'~(*ANYCRLF)\S+(?=\*$)~m'
(* ANYCRLF)指定换行约定:(* CR),(* LF)或(* CRLF),等同于PCRE_NEWLINE_ANY选项.见PCRE documentation:
PCRE_NEWLINE_ANY
specifies that any Unicode newline sequence should be recognized.
最后,这个PCRE动词启用.匹配任何字符但是CR和LF符号和$将在这两个字符之前匹配.
在rexegg.com查看有关此动词和其他动词的更多信息:
By default, when PCRE is compiled, you tell it what to consider to be a line break when encountering a
.
(as the dot it doesn’t match line breaks unless in 07002), as well the^
and$
anchors’ behavior in 07003. You can override this default with the following modifiers:✽
(*CR)
Only a carriage return is considered to be a line break
✽(*LF)
Only a line feed is considered to be a line break (as on Unix)
✽(*CRLF)
Only a carriage return followed by a line feed is considered to be a line break (as on Windows)
✽(*ANYCRLF)
Any of the above three is considered to be a line break
✽(*ANY)
Any Unicode newline sequence is considered to be a line breakFor instance,
(*CR)\w+.\w+
matches Line1\nLine2 because the dot is able to match the \n, which is not considered to be a line break. See 07004.