preg_replace确实删除了一个组,而它应该在替换中使用它

时间:2018-05-07 13:03:22

标签: php regex preg-replace

给出原始字符串:

<p>my text 1</p>
some other content
<p>some other paragraph followed by an html line break</p><br>
etc...

- 我们假设 - 是$str

的值

以及以下治疗顺序:

$str=nl2br($str);

现在我们有:

<p>my text 1</p><br />
some other content<br />
<p>some other paragraph followed by an html line break</p><br><br />
etc...<br />

......,没关系。然后:

$str=preg_replace('/(<\/p>)<br.{0,2}\/>/',${1}, $str);

我希望此代码能够删除在结束<br />之后放置的所有HTML <br><br/></p>标记。

php如何给我:

php > echo $str;
<p>my text 1
some other content<br />
<p>some other paragraphfollowed by an html line break</p><br><br />
etc...<br />
php > 

我宁愿期待:

<p>my text 1</p>
some other content<br />
<p>some other paragraph followed by an html line break</p><br>
etc...<br />

3 个答案:

答案 0 :(得分:4)

替换字符串中使用的反向引用格式错误,不应该是${1},而是'$1'(引用!)。同样由<br.{0,2}\/>提交<br>,因为您必须使用一个斜杠。考虑到上述所有因素,这是一个解决方案:

$str = preg_replace('~(</p>)<br ?/?>~', '$1', $str);

Live demo

答案 1 :(得分:1)

我认为你说的是​​:

  1. 您希望保留预先存在的<br>代码和
  2. 添加<br>标记,其中存在换行符,但前面没有html标记(特别是您的示例输入 - </p>)。
  3. 如果这是您的编码意图的核心,那么您可以省略nl2br()步骤(以及随后的mopping-up正则表达式调用),并且只定位以文本而不是标记结尾的行。

    *如果这对您的实际项目不起作用,您必须调整或解释您的样本数据与实际数据之间的差异。

    代码:(Demo)(Pattern Demo

    $string = <<<HTML
    <p>my text 1</p>
    some other content
    <p>some other paragraph followed by an html line break</p><br>
    etc...
    HTML;
    
    $string = preg_replace('~</?[a-z]+>\R(*SKIP)(*FAIL)|$~m', '<br>', $string);
    
    var_export($string);                   // output
    echo "\n----\n";
    var_export(json_encode($string));      // encoded output (to show newline characters retained)
    

    输出:

    '<p>my text 1</p>
    some other content<br>
    <p>some other paragraph followed by an html line break</p><br>
    etc...<br>'
    ----
    '"<p>my text 1<\\/p>\\nsome other content<br>\\n<p>some other paragraph followed by an html line break<\\/p><br>\\netc...<br>"'
    

    基本上,我认为你可以更直接地完成这项任务。这是模式细分:

    ~               #start of pattern delimiter
    </?[a-z]+>      #match less than symbol, optional forward slash, one or more letters, greater than symbol
    \R              #match newline character(s)  ...you can add match one or more if suitable for your project
    (*SKIP)(*FAIL)  #discard the characters matched (disqualify the match / do not replace)
    |               #or
    $               #the end of a line
    ~               #end of pattern delimiter
    m               #multiline pattern modifier, tells regex to treat $ as end of line not end of string
    

答案 2 :(得分:0)

这将满足您的需求:

<?php

$text = '<p>my text 1</p>
some other content
<p>some other paragraph followed by an html line break</p><br>
etc...';

$text = nl2br($text);

$regex= '#<\/p>(<br\s?\/?>)#';
$text = preg_replace($regex, '</p>', $text);
echo $text;

查看正则表达式如何匹配https://regex101.com/r/0gPhL3/1

检查此处的代码https://3v4l.org/2RkFb