问题描述
我有以下最小示例,它们在本地服务器(WAMP、PHP 7.3.7)和使用 PHP 7.3.27 的生产服务器上的行为不同。本地服务器上的结果对我来说似乎是错误的,因为惰性修饰符被忽略了。结果也和我试过的所有正则表达式测试器都有冲突。
示例代码:
<?PHP
header('Content-Type: text/plain; charset=utf-8');
$input = <<<EOT
John Smith
John Smith (123)
John Smith (123) (456)
EOT;
preg_match_all('/(.+?)(?:\s\((\d+)\))?$/m',$input,$matches_defines);
print_r($matches_defines);
?>
本地环境中的结果:
Array
(
[0] => Array
(
[0] => John Smith
[1] => John Smith (123)
[2] => John Smith (123) (456)
)
[1] => Array
(
[0] => John Smith
[1] => John Smith (123)
[2] => John Smith (123)
)
[2] => Array
(
[0] =>
[1] =>
[2] => 456
)
)
生产环境中的结果:
Array
(
[0] => Array
(
[0] => John Smith
[1] => John Smith (123)
[2] => John Smith (123) (456)
)
[1] => Array
(
[0] => John Smith
[1] => John Smith
[2] => John Smith (123)
)
[2] => Array
(
[0] =>
[1] => 123
[2] => 456
)
)
谁能告诉我这种差异来自哪里,可以在当地环境中进行哪些调整来纠正它?
解决方法
好的,在这里回答我自己的问题:这是一个 Windows/Linux 行尾问题。
我本地服务器上的正则表达式失败,因为在文本中,每个右括号后面都有一个 \r
。所以右括号不是行尾,在行尾(\r
)之前还有一个额外的字符$
。 (Source)
这可以通过稍微修改的正则表达式来解决:/(.+?)(?:\s\((\d+)\))?\s*$/m
。
请注意末尾的 \s*
。这与行尾的 \r
匹配(如果存在)。