【问题标题】:php explode: split string into words by using space a delimiterphp爆炸:使用空格分隔符将字符串拆分为单词
【发布时间】:2013-09-09 10:20:48
【问题描述】:
$str = "This is a    string";
$words = explode(" ", $str);

工作正常,但空格仍然进入数组:

$words === array ('This', 'is', 'a', '', '', '', 'string');//true

我希望只包含没有空格的单词,并将关于空格数的信息分开。

$words === array ('This', 'is', 'a', 'string');//true
$spaces === array(1,1,4);//true

刚刚添加:(1, 1, 4) 表示第一个单词后一个空格,第二个单词后一个空格,第三个单词后四个空格。

有什么方法可以快速完成吗?

谢谢。

【问题讨论】:

  • 你要的是空格数还是每个空格的位置?
  • @JasonMcCreary 他要每个空间组的连续空格数:' ' (1), ' ' (1), ' ' (4)
  • 谢谢。空格数。
  • @Haradzieniec,我认为您不了解其中的区别。 空格数 = 6。这不是你想要的。

标签: php arrays regex preg-match explode


【解决方案1】:

要将字符串拆分为数组,应使用preg_split:

$string = 'This is a    string';
$data   = preg_split('/\s+/', $string);

你的第二部分(计算空格):

$string = 'This is a    string';
preg_match_all('/\s+/', $string, $matches);
$result = array_map('strlen', $matches[0]);// [1, 1, 4]

【讨论】:

  • the number of spaces 关于提问者的预期在哪里?
  • 感谢您的回答。但是,您会丢失有关两者之间的空格数的信息。这就是我在问题中提出的问题(请参阅粗体文本)。
  • @Haradzieniec 只是输入,是的。谢谢你,我已经更新了。
【解决方案2】:

这是一种方法,拆分字符串并运行一次正则表达式,然后解析结果以查看哪些段被捕获为拆分(因此只有空格),或者哪些是单词:

$temp = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
    if( strlen( trim( $item)) === 0) {
        $spaces[] = strlen( $item);
    } else {
        $result[] = $item;
    }
    return $result;
}, array());

你可以看到from this demo那个$words是:

Array
(
    [0] => This
    [1] => is
    [2] => a
    [3] => string
)

$spaces 是:

Array
(
    [0] => 1
    [1] => 1
    [2] => 4
)

【讨论】:

  • 非常感谢您的回答。我已经测试了您和 Alma Do Mundo / Silkfire 解决方案。所有解决方案都可以正常工作,但 Alma Do Mundo 的工作速度要快两倍。无论如何,感谢您的解决方案。如果需要,您可以比较两者(请稍后查看我对我自己的问题的回复)。
【解决方案3】:

您可以将preg_split() 用于第一个数组:

$str   = 'This is a    string';
$words = preg_split('#\s+#', $str);

preg_match_all() 代表 $spaces 数组:

preg_match_all('#\s+#', $str, $m);
$spaces = array_map('strlen', $m[0]);

【讨论】:

  • 1, 1, 4 表示第一个单词后一个空格,第二个单词后一个空格,第三个单词后四个空格。
【解决方案4】:

另一种方法是使用 foreach 循环。

$str = "This is a    string";
$words = explode(" ", $str);
$spaces=array();
$others=array();
foreach($words as $word)
{
if($word==' ')
{
array_push($spaces,$word);
}
else
{
array_push($others,$word);
}
}

【讨论】:

  • 谢谢。但是,它会收集空格,但不包含有关单词之间空格数的信息。
  • 这个答案被证明是不正确的。 3v4l.org/Tq66W
【解决方案5】:

以下是性能测试结果:

$str = "This is a    string";

var_dump(time());

for ($i=1;$i<100000;$i++){
//Alma Do Mundo  - the winner
$rgData = preg_split('/\s+/', $str);


preg_match_all('/\s+/', $str, $rgMatches);
$rgResult = array_map('strlen', $rgMatches[0]);// [1,1,4]


}
print_r($rgData); print_r( $rgResult);
var_dump(time());




for ($i=1;$i<100000;$i++){
//nickb
$temp = preg_split('/(\s+)/', $str, -1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
    if( strlen( trim( $item)) === 0) {
        $spaces[] = strlen( $item);
    } else {
        $result[] = $item;
    }
    return $result;
}, array());
}


print_r( $words); print_r( $spaces);
var_dump(time());

int(1378392870) 大批 ( [0] => 这个 [1] => 是 [2] => 一个 [3] => 字符串 ) 大批 ( [0] => 1 [1] => 1 [2] => 4 ) 整数(1378392871) 大批 ( [0] => 这个 [1] => 是 [2] => 一个 [3] => 字符串 ) 大批 ( [0] => 1 [1] => 1 [2] => 4 ) 整数(1378392873)

【讨论】:

  • 我很惊讶地看到两个正则表达式调用在某种程度上优于单个正则表达式调用。
【解决方案6】:

$financialYear = 2015-2016;

$test = explode('-',$financialYear);
echo $test[0]; // 2015
echo $test[1]; // 2016

【讨论】:

  • 这和问题不一样!并且晚了几年。
【解决方案7】:

早先的答案已经很好地证明了使用正则表达式进行拆分,但我认为这是调用ctype_space() 来确定哪个结果数组应该接收遇到的值的完美案例。

代码:(Demo)

$string = "This is a    string";

$words = [];
$spaces = [];

foreach (preg_split('~( +)~', $string, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $s) {
    if (ctype_space($s)) {
        $spaces[] = strlen($s);
    } else {
        $words[] = $s;
    }
}

var_export([
    'words' => $words,
    'spaces' => $spaces
]);

输出:

array (
  'words' => 
  array (
    0 => 'This',
    1 => 'is',
    2 => 'a',
    3 => 'string',
  ),
  'spaces' => 
  array (
    0 => 1,
    1 => 1,
    2 => 4,
  ),
)

如果你想替换preg_split() 使用的管道常量,你可以使用3 (Demo)。这表示PREG_SPLIT_NO_EMPTY1 加上PREG_SPLIT_DELIM_CAPTURE2。请注意,随着代码宽度的减少,您也会失去代码的可读性。

preg_split('~( +)~', $string, -1, 3)

【讨论】:

    【解决方案8】:

    这个呢?有人愿意介绍这个吗?

        $str = str_replace(["\t", "\r", "\r", "\0", "\v"], ' ', $str); // \v -> vertical space, see trim()
        $words = explode(' ', $str);
        $words = array_filter($words); // there would be lots elements from lots of spaces so skip them.
    

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 2014-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      相关资源
      最近更新 更多