与PHP正则表达式匹配行尾的差异

与PHP正则表达式匹配行尾的差异,php,regex,php-7,php-7.3,Php,Regex,Php 7,Php 7.3,鉴于代码: $my_str = ' Rollo is* My dog* And he\'s very* Lovely* '; preg_match_all('/\S+(?=\*$)/m', $my_str, $end_words); print_r($end_words); 在PHP7.3.2(XAMPP)中,我得到了意外的输出 Array ( [0] => Array ( ) ) 而在PHP 7.0.33中,我得到了我所期望的: Array ( [0] => Array (

鉴于代码:

$my_str = '
Rollo is*
My dog*
And he\'s very*
Lovely*
';

preg_match_all('/\S+(?=\*$)/m', $my_str, $end_words);
print_r($end_words);
在PHP7.3.2(XAMPP)中,我得到了意外的输出

Array ( [0] => Array ( ) )
而在PHP 7.0.33中,我得到了我所期望的:

Array ( [0] => Array ( [0] => is [1] => dog [2] => very [3] => Lovely ) ) 

有谁能告诉我为什么会有这样的差异,7.0.33之后正则表达式的行为是否发生了变化?

在您所处的环境中,PCRE库的编译没有使用
PCRE\u NEWLINE\u任何
选项,在多行模式下,
$
仅在LF符号之前匹配,
匹配除LF以外的任何符号

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

'~(*ANYCRLF)\S+(?=\*$)~m'
(*ANYCRLF)
指定换行约定:
(*CR)
(*LF)
(*CRLF)
,等同于
PCRE\u newline\u ANY
选项。见:

PCRE\u NEWLINE\u ANY
指定应识别任何Unicode换行符序列

最后,此PCRE动词使
能够匹配任何字符,但CR和LF符号除外,
$
将在这两个字符之前匹配

有关此动词和其他动词的详细信息,请参见:

默认情况下,当编译PCRE时,你告诉它在遇到<代码>时要考虑什么是断线。<代码>(作为点,它不匹配行中断,除非在IN中),以及<代码> ^ < /代码>和<代码> $< /代码>锚的行为。可以使用以下修改器替代此默认值:

✽ <代码>(*CR)只有回车被认为是换行符
(*LF)
只有换行符被认为是换行符(在Unix上)
✽ <代码>(*CRLF)只有回车符后加换行符才被视为换行符(如在Windows上)
(*ANYCRLF)
上述三种情况中的任何一种都被视为断线
(*ANY)
任何Unicode换行符序列都被视为换行符

例如,
(*CR)\w+。\w+
匹配第1行\n行,因为点能够匹配第\n行,这不被认为是换行符。看


如果某个东西是版本差异,而不是平台或配置差异,那么一个有用的测试站点就是在这种情况下,所以在您的测试环境中还有一些其他差异。我的猜测与Windows与Unix行结尾有关。在测试上述代码时,我无法重现您的问题。这将测试7.1.25-7.3.3,并给出预期结果。如果你检查“eol版本”,它会通过命令行测试从4.3版本到7.3.3版本的所有版本,我也看到了同样的故障(空数组)。我在Ubuntu机器上通过CLI测试了7.3.2和7.3.3版本,它仍然给了我预期的结果。@WiktorStribiżew我不认为这很简单或明显,但谢谢:-)真奇怪。我唯一能想到的是,当我安装XAMPP时,我取消了“安装Perl”。我知道PCRE源于Perl,所以这可能是造成这种情况的原因吗?@Utkanos我不认为它有任何影响。问题在于PCRE库是如何编译的。注意PCRE正则表达式库与Perl中使用的不同。