【问题标题】:Split a string on different substrings, but conserve those substrings在不同的子字符串上拆分字符串,但保留这些子字符串
【发布时间】:2013-09-18 23:48:36
【问题描述】:

我正在尝试拆分以下字符串:

Hello how are you<br>Foo bar hello

进入

"Hello", " how", " are", " you", "<br>", " Foo", " bar", " Hello"

这可能吗?

【问题讨论】:

  • 在空间爆炸和
  • 到目前为止你有什么?它会一直是空格和&lt;br&gt; 你想从中分割吗?
  • 如果您在
    之前有空格,您希望输出是什么?
  • 灭霸,在这种情况下应该是“
    ”。这样做的全部原因是我使用了一个文本差异引擎,它将“Hello
    Something”视为一个单词。
  • 你可以把
    替换成空格,或者去掉所有的 html ?

标签: php regex string split


【解决方案1】:

不要让事情变得比你必须做的更难。将preg_split()PREG_SPLIT_DELIM_CAPTURE 标志一起使用,并捕获&lt;br&gt;

$str = 'Hello how are you<br>Foo bar hello';
$array = preg_split( '/\s+|(<br>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r( $array);

Output:

Array 
( 
    [0] => Hello 
    [1] => how 
    [2] => are 
    [3] => you 
    [4] => <br> 
    [5] => Foo 
    [6] => bar 
    [7] => hello
)

编辑:要在以下标记中包含空格,您可以使用断言:

$array = preg_split( '/(?:\s*(?=\s))|(<br>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);

所以,preg_split() 的目标是在字符串中找到一个点进行拆分。我们使用的正则表达式由两部分组成,OR'd 和 |

  1. (?:\s*(?=\s))。这从一个非捕获组(?:) 开始,因为当我们匹配这部分正则表达式时,我们不希望它返回给我们。在非捕获组内,是\s*(?=\s),它表示“匹配零个或多个空白字符,但断言下一个字符是空白字符”。查看我们的输入字符串,这是有道理的:

    Hello how are you<br>Foo bar hello
         ^   ^
    

    正则表达式将从左到右开始,找到“Hello{space}how”,并决定如何拆分字符串。它尝试匹配\s* 的限制,即如果它消耗任何空间,则需要留下一个空间。因此,它仅在"Hello" 处分解字符串。当它继续时,它会留下“你好吗
    Foo bar hello”。它再次开始匹配,试图从它停止的地方匹配,并看到“how are”,并进行与上面相同的拆分。它会一直持续到没有匹配项为止。

  2. 使用(&lt;br&gt;) 捕获&lt;br&gt;。它被捕获是因为当我们匹配它时,我们希望将它保留在输出中,因此将它与 PREG_SPLIT_DELIM_CAPTURE 一起捕获会导致它在匹配时返回给我们(而不是完全消耗)。

这个results in

array(8) 
{ 
    [0]=> string(5) "Hello" 
    [1]=> string(4) " how" 
    [2]=> string(4) " are" 
    [3]=> string(4) " you" 
    [4]=> string(4) "<br>" 
    [5]=> string(3) "Foo" 
    [6]=> string(4) " bar" 
    [7]=> string(6) " hello" 
}

【讨论】:

  • 您能想到任何可以在结果前添加空格的调整吗?例如:[0] => "Hello", [1] => "how",...(注意 "how" 上的空格)
  • @Boni - 是的,断言应该不会太糟糕。给我几分钟,我会更新我的答案。
  • @Boni - 查看我的更新答案。这是你要找的吗?
  • @Boni - 当然,我已经用解释更新了我的答案。现在我正在查看它,因为您在单词之间没有多个空格,您可以将正则表达式更改为 /(?=\s)|(&lt;br&gt;)/,它应该仍然有效。
  • 实际上并没有按要求处理所有标签。
【解决方案2】:

不漂亮,但足够简单:

$data = 'Hello how are you<br>Foo bar hello';
$split = array();
foreach (explode('<br>', $data) as $line) {
  $split[] = array_merge($split, explode(' ', $line));
  $split[] = '<br>';
}
array_pop($split);

print_r($split);

或版本 2:

$data = 'Hello how are you<br>Foo bar hello';
$data = preg_replace('#\s|(<br>)#', '**$1**', $data);
$split = array_filter(explode('**', $data));
print_r($split);

【讨论】:

    【解决方案3】:

    这就是我的做法:

    1. 用空格作为分隔符分解字符串
    2. 循环遍历各个部分
    3. 使用strpos 并检查部件是否包含给定的标签——在这种情况下为&lt;br&gt;
    4. 如果是这样,用标签作为分隔符再次分解字符串
    5. 将这三个项目全部压入结果数组中
    6. 如果没有,则将其推入结果数组中

    代码:

    $str = 'Hello how are you<br>Foo bar hello';
    $parts = explode(' ', $str);
    $result = array();
    
    foreach ($parts as $part) {
        if(strpos($part, '<br>') !== FALSE) {
            $arr = explode('<br>', $part);
            $result = array_merge($result, $arr);    
            $result[] = "<br>";
        }
        else {
            $result[] = $part;
        }
    }
    print_r($result);
    

    输出:

    Array
    (
        [0] => Hello
        [1] => how
        [2] => are
        [3] => you
        [4] => Foo
        [5] => <br>
        [6] => bar
        [7] => hello
    )
    

    Demo!

    【讨论】:

      【解决方案4】:

      这是一个简短的解决方案。将&lt;br&gt;替换为(空格&lt;br&gt;空格)并使用空格分割:

      <?php
         $newStr=str_replace("<br>"," <br> ","Hello how are you<br>Foo bar hello");
         $str= explode(' ',$newStr);   
      ?>
      

      print_r($str) 的输出:

      (
          [0] => Hello
          [1] => how
          [2] => are
          [3] => you
          [4] => <br>
          [5] => Foo
          [6] => bar
          [7] => hello
      )
      

      【讨论】:

        【解决方案5】:

        @nickb 的答案中借用preg_split 模式:

        <?php
        $string = 'Hello how are you<br>Foo bar hello';
        
        $array = preg_split('/\s/',$string);
        
        foreach($array as $key => $value) {
            $a = preg_split( '/\s+|(<br>)/', $value, -1, PREG_SPLIT_DELIM_CAPTURE);
            if(is_array($a)) {
                foreach($a as $key2 => $value2) {
                    $result[] = $value2;
                }
            }
        }
        
        print_r($result);
        ?>
        

        输出:

        Array
        (
            [0] => Hello
            [1] => how
            [2] => are
            [3] => you
            [4] => <br>
            [5] => Foo
            [6] => bar
            [7] => hello
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-08-29
          • 1970-01-01
          • 1970-01-01
          • 2018-12-23
          • 2019-10-11
          • 2020-07-09
          • 1970-01-01
          相关资源
          最近更新 更多