4

给定代码:

$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 行为是否发生了变化?

4

1 回答 1

1

似乎在您拥有的环境中,PCRE 库是在没有PCRE_NEWLINE_ANY选项的情况下编译的,并且$在多行模式下仅匹配 LF 符号之前并.匹配除 LF 之外的任何符号。

您可以使用 PCRE(*ANYCRLF)动词来修复它:

'~(*ANYCRLF)\S+(?=\*$)~m'

(*ANYCRLF)指定换行约定:(*CR),(*LF)(*CRLF)并且等价于PCRE_NEWLINE_ANY选项。请参阅PCRE 文档

PCRE_NEWLINE_ANY指定应识别任何 Unicode 换行符序列。

最后,这个 PCRE 动词能够.匹配除 CR 和 LF 符号之外的任何字符,$并将在这两个字符中的任何一个之前匹配。

在rexegg.com上查看有关此动词和其他动词的更多信息:

默认情况下,当 PCRE 被编译时,你告诉它遇到 a 时认为什么是换行符.(因为点它不匹配换行符,除非在dotall 模式下),以及^$锚点在多行模式下的行为。您可以使用以下修饰符覆盖此默认值:

(*CR)只有回车被认为是换行符
(*LF)只有换行被认为是换行符(如在 Unix 上)
(*CRLF)只有回车后跟换行符被认为是换行符(如在 Windows )
(*ANYCRLF)上述三个中的任何一个都被认为是换行符
(*ANY)任何 Unicode 换行符序列都被认为是换行符

例如,(*CR)\w+.\w+匹配Line1\nLine2因为点能够匹配\n,这不被视为换行符。见演示

于 2019-03-19T12:47:22.287 回答