如何更改PCRE正则表达式认为多线模式的换行符?

MrW*_*ite 7 php regex pcre preg-match

使用PHP中的PCRE正则表达式,多行模式(/m)启用^$匹配源文本中行的开始和结束(由换行符分隔),以及源文本的开头和结尾.

这似乎在Linux上运行良好,其中\n(LF)是换行符分隔符,但在Windows上使用\r\n(CRLF)失败.

有没有办法改变PCRE认为的新行?或者也许允许它以匹配$行尾/字符串的相同方式匹配CRLF或LF ?

例:

$EOL = "\n";    // Linux LF
$SOURCE_TEXT = "one{$EOL}two{$EOL}three{$EOL}four";
if (preg_match('/^two$/m',$SOURCE_TEXT)) {
    echo 'Found match.';    // <<< RESULT
} else {
    echo 'Did not find match!';
}
Run Code Online (Sandbox Code Playgroud)

结果:成功

$EOL = "\r\n";    // Windows CR+LF
$SOURCE_TEXT = "one{$EOL}two{$EOL}three{$EOL}four";
if (preg_match('/^two$/m',$SOURCE_TEXT)) {
    echo 'Found match.';
} else {
    echo 'Did not find match!';    // <<< RESULT
}
Run Code Online (Sandbox Code Playgroud)

结果:失败

小智 9

你试过(*CRLF)和相关的修饰符了吗?他们在维基百科上详细这里(下换行/断行选项),并似乎做正确的事在我的测试.即'/(*CRLF)^two$/m'应匹配Windows \r\n换行符.也(*ANYCRLF)应该匹配Linux和Windows,但我还没有测试过.

  • 是的,这对我来说也适用(包括`(*ANYCRLF)`)在模式开始时指定.请注意,这些修饰符自PCRE 7.3起可用,[对应于PHP 5.2.5](http://www.php.net/manual/en/pcre.installation.php). (2认同)

hak*_*kre 5

注意:答案是只适用于老版本PHP,当我写的,我不知道可用的序列和修饰的:\R,(*BSR_ANYCRLF)(*BSR_UNICODE).请参阅以下答案:如何以最智能的方式在PHP中替换不同的换行符样式?

在PHP中,无法为PCRE正则表达式模式指定换行符字符序列.该m修改正在寻找\n只,多数民众赞成记录.并且没有可用于进行更改的运行时设置,这在perl中是可能的,但这不是PHP的选项.

我通常只是在使用之前修改字符串preg_match等:

$subject = str_replace("\r\n", "\n", $subject);
Run Code Online (Sandbox Code Playgroud)

这可能不是您正在寻找的,但可能有帮助.

编辑:关于Windows EOL示例,您已添加到您的问题:

$EOL = "\r\n";    // Windows CR+LF
$SOURCE_TEXT = "one{$EOL}two{$EOL}three{$EOL}four";
if (preg_match('/^two$/m',$SOURCE_TEXT)) {
    echo 'Found match.';
} else {
    echo 'Did not find match!';    // <<< RESULT
}
Run Code Online (Sandbox Code Playgroud)

这失败了,因为在文本中,有一个\rtwo.所以two不是在一行\r的末尾,在行结束之前还有一个额外的字符($).

PHP手册清楚地解释了只\n被视为指定行结尾的字符.只$考虑\n,所以如果你在two\r一行的末尾寻找,你需要改变你的模式.这是另一种选择(而不是如上所述转换文本).