PHP - 改进Regex(空间和非捕获组)

时间:2015-04-16 10:27:20

标签: php regex

我有这种字符串:

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

我试图在" ""<br />"preg_split之间爆炸每个单词。

我的条件:

对于每个单词(Blablax),我需要保留他的标记,例如<strong><span><em> ...但是在<br />之后将其分开}或更多<br />

我试过这个,感谢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(见上文OUTPUT)和index 9以及index 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

我的正则表达式有效,如果我只有一个<br />,但如果不止一个,则会出现错误......如果我有一个<span style...>

谢谢!

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

查看索引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?

答案 2 :(得分:0)

这是正则表达式

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

使用preg_replace使用$1\n作为替换字符串,然后您可以按换行分割以获取数组(删除空数组)。

请参阅demo