在不同的子字符串上拆分字符串,但保留这些子字符串

时间:2013-09-18 23:48:37

标签: php regex string split

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

Hello how are you<br>Foo bar hello

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

这可能吗?

5 个答案:

答案 0 :(得分:3)

不要让事情变得更难。将preg_split()PREG_SPLIT_DELIM_CAPTURE标记一起使用,然后捕获<br>

$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”。它再次开始比赛,尝试从它离开的位置进行匹配,并看到“如何”,并进行与上面相同的拆分。它一直持续到没有比赛为止。

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

  3. 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" 
    }
    

答案 1 :(得分:1)

不漂亮,但很简单:

$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);

答案 2 :(得分:0)

我就是这样做的:

  1. 以空格作为分隔符
  2. 分解字符串
  3. 循环部分
  4. 使用strpos并检查部分是否包含给定标记 - 在这种情况下为<br>
  5. 如果是,请使用标记作为分隔符再次爆炸字符串
  6. 将所有三个项目推送到结果数组
  7. 如果没有,则将其推入结果数组
  8. 代码:

    $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!

答案 3 :(得分:0)

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

<?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
)

答案 4 :(得分:0)

@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
)