【问题标题】:PHP - Improve Regex (space and non-capturing group)PHP - 改进正则表达式(空间和非捕获组)
【发布时间】:2015-04-16 10:27:19
【问题描述】:

我有这种字符串:

$string = "<strong>Blabla1</strong> Blaabla2<br /> Blaabla3 <strong>Blaabla4</strong> Blaabla5 Blaabla6<br /><br /> Blaabla7 <span style='color:#B22222;'>Blaabla8</span> Blaabla9";

我正在尝试用 preg_split 爆炸每个有 " ""&lt;br /&gt;" 的单词。

我的条件:

对于每个单词 (Blablax),我需要保留他的标签,例如 &lt;strong&gt;&lt;span&gt;&lt;em&gt;... 但在 &lt;br /&gt; 或更多 &lt;br /&gt; 之后拆分他

我试过了,感谢 stackoverflow 上的另一篇文章:

preg_split('/<br(\s\/)?>\K|\s/',$string,null,PREG_SPLIT_NO_EMPTY);

输出:

array (size=12)
  0 => string '<strong>Blabla1</strong>' (length=24)
  1 => string 'Blaabla2<br />' (length=14)
  2 => string 'Blaabla3' (length=8)
  3 => string '<strong>Blaabla4</strong>' (length=25)
  4 => string 'Blaabla5' (length=8)
  5 => string 'Blaabla6<br />' (length=14)
  6 => string '<br' (length=3)
  7 => string '/>' (length=2)
  8 => string 'Blaabla7' (length=8)
  9 => string '<span' (length=5)
  10 => string 'style='color:#B22222;'>Blaabla8</span>' (length=38)
  11 => string 'Blaabla9' (length=8)

对于index 6index 7(见上面的输出)和index 9index 10,一切都除了

我的期望:

array (size=12)
      0 => string '<strong>Blabla1</strong>' (length=24)
      1 => string 'Blaabla2<br />' (length=14)
      2 => string 'Blaabla3' (length=8)
      3 => string '<strong>Blaabla4</strong>' (length=25)
      4 => string 'Blaabla5' (length=8)
      5 => string 'Blaabla6<br /><br />' (length=14)
      6 => string 'Blaabla7' (length=8)
      7 => string '<span style='color:#B22222;'>Blaabla8</span>' (length=45)
      8 => string 'Blaabla9' (length=8)

index 5index 7

如果我只有一个&lt;br /&gt;,我的正则表达式可以工作,但如果有多个,就会出现错误...如果我有&lt;span style...&gt;,则同上

谢谢!

【问题讨论】:

  • 试试preg_split('/&lt;br(\s\/)?&gt;\K|\s/g',$string,null,PREG_SPLIT_NO_EMPTY);
  • 为什么在索引 1 处多了一个 &lt;br /&gt;?它不存在于输入中。
  • @nhahtdh 我的错...我编辑了我的帖子...索引 1 处没有多余的 &lt;br /&gt;...
  • 看看您对索引 7 的要求,我认为您最好使用 PHP 解析器。 stackoverflow.com/questions/3577641/…

标签: php regex


【解决方案1】:
$string = "<strong>Blabla1</strong> Blaabla2<br /> Blaabla3 <strong>Blaabla4</strong> Blaabla5 Blaabla6<br /><br /> Blaabla7 <span style='color:#B22222;'>Blaabla8</span> Blaabla9";

$matches = preg_split('/(<br.*?>|<span.*>)+\K|\s/sim', $string, null, PREG_SPLIT_NO_EMPTY );

var_dump($matches);
    /*
      array(9) {
  [0]=>
  string(24) "<strong>Blabla1</strong>"
  [1]=>
  string(14) "Blaabla2<br />"
  [2]=>
  string(8) "Blaabla3"
  [3]=>
  string(25) "<strong>Blaabla4</strong>"
  [4]=>
  string(8) "Blaabla5"
  [5]=>
  string(20) "Blaabla6<br /><br />"
  [6]=>
  string(8) "Blaabla7"
  [7]=>
  string(44) "<span style='color:#B22222;'>Blaabla8</span>"
  [8]=>
  string(8) "Blaabla9"
}
    */

DEMO

【讨论】:

    【解决方案2】:

    查看索引 5 和索引 7 处的预期数组,您可能需要这个正则表达式:

    preg_split('~(?:</?[a-zA-Z0-9][^>]*+>|\S)++\K|\s~',$string,null,PREG_SPLIT_NO_EMPTY);
    

    Demo on ideone

    输出:

    array(9) {
      [0]=>
      string(24) "<strong>Blabla1</strong>"
      [1]=>
      string(14) "Blaabla2<br />"
      [2]=>
      string(8) "Blaabla3"
      [3]=>
      string(25) "<strong>Blaabla4</strong>"
      [4]=>
      string(8) "Blaabla5"
      [5]=>
      string(20) "Blaabla6<br /><br />"
      [6]=>
      string(8) "Blaabla7"
      [7]=>
      string(44) "<span style='color:#B22222;'>Blaabla8</span>"
      [8]=>
      string(8) "Blaabla9"
    }
    

    正则表达式尝试匹配一个完整的标签,如果一个完整的标签不能被消费,它将消费一个非空格字符,然后冲洗并重复。这将防止标签被拆分,从而为索引 5 和 7 提供预期的输出。

    不过,我不建议使用正则表达式。我在编写正则表达式时没有参考 HTML 规范,因此正则表达式非常脆弱,可能会在野外输入时中断。您可能想了解如何使用此问题中列出的库之一正确解析 HTML:How do you parse and process HTML/XML in PHP?

    【讨论】:

    • 感谢您的解释!我会看到你的链接:)
    【解决方案3】:

    这里是正则表达式

    ((?:<br\s*\/?>)+)|(?<!<br)\s+(?!\/?>)
    

    将此与preg_replace 一起使用,使用$1\n 作为替换字符串,然后您可以通过换行符拆分以获取数组(删除空数组)。

    demo

    【讨论】:

      猜你喜欢
      • 2015-06-21
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多