【问题标题】:Including new lines in PHP preg_replace function在 PHP preg_replace 函数中包含新行
【发布时间】:2010-10-16 06:55:36
【问题描述】:

我正在尝试匹配可能出现在多行上的字符串。它以特定的字符串开头和结尾:

{a}some string
can be multiple lines
{/a}

我可以使用正则表达式获取{a}{/a} 之间的所有内容吗?看来.不匹配新行,但我尝试了以下但没有运气:

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/', 'X', $template, -1, $count );
echo $count; // prints 0

匹配。或\n当他们独自一人但不在一起时!

【问题讨论】:

    标签: php regex newline


    【解决方案1】:

    使用s modifier

    $template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/s', 'X', $template, -1, $count );
    //                                                ^
    echo $count;
    

    【讨论】:

    【解决方案2】:

    我认为您遇到的问题不仅仅是点不匹配换行符,但让我从格式建议开始。您可以使用几乎任何标点符号作为正则表达式分隔符,而不仅仅是斜杠 ('/')。如果您使用另一个字符,则不必在正则表达式中转义斜杠。我知道 '%' 在 PHPers 中很流行;这将使您的模式论点:

    '%\{a\}([.\n]+)\{/a\}%'
    

    现在,正则表达式没有按您的预期工作的原因是,当它出现在字符类(方括号)中时,点失去了它的特殊含义——所以[.\n] 只匹配一个点或换行符。您要查找的是 (?:.|\n),但我建议匹配回车符和换行符:

    '%\{a\}((?:.|[\r\n])+)\{/a\}%'
    

    这是因为“换行符”这个词可以指代 Unix 风格的“\n”、Windows 风格的“\r\n”或旧 Mac 风格的“\r”。任何给定的网页可能包含其中任何一种或两种或多种样式的混合; "\n" 和 "\r\n" 的混合很常见。但是使用 /s 模式(也称为单行或 DOTALL 模式),您无需担心:

    '%\{a\}(.+)\{/a\}%s'
    

    但是,原始正则表达式存在另一个问题:+ 是贪婪的。这意味着,如果文本中有多个{a}...{/a} 序列,则第一次应用您的正则表达式时,它将匹配所有这些序列,从第一个{a} 到最后一个{/a}。解决这个问题的最简单方法是通过附加问号使 + 不贪婪(又名“懒惰”或“不情愿”):

    '%\{a\}(.+?)\{/a\}%s'
    

    最后,我不知道你的模式参数的开头引号之前的“$”是什么意思。我不做 PHP,但这对我来说似乎是一个语法错误。如果有人能在这件事上教育我,我将不胜感激。

    【讨论】:

    • 哦,那一定是一个错字——我最初在那里使用了一个变量,并在这个例子中用一个字符串替换了它。
    • 这是一个很好的解释。为此干杯。
    【解决方案3】:

    来自http://www.regular-expressions.info/dot.html

    "点匹配单个字符, 不在乎那个角色是什么。 唯一的例外是换行符 字符。”

    您需要在表达式中添加尾随 /s 标志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 2012-10-10
      • 2012-10-23
      • 2015-02-03
      • 2011-09-18
      • 2018-09-12
      相关资源
      最近更新 更多