PHP爆炸string,但将引号中的单词作为单个单词处理

我怎样才能爆炸下面的string:

Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor 

 array("Lorem", "ipsum", "dolor sit amet", "consectetur", "adipiscing elit", "dolor") 

这样引文中的文字被视为一个单词。

这是我现在所拥有的:

 $mytext = "Lorem ipsum %22dolor sit amet%22 consectetur %22adipiscing elit%22 dolor" $noquotes = str_replace("%22", "", $mytext"); $newarray = explode(" ", $noquotes); 

但我的代码将每个单词分成一个数组。 我怎样才能把引号内的单词当作一个单词处理?

你可以使用preg_match_all(...)

 $text = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing \\"elit" dolor'; preg_match_all('/"(?:\\\\.|[^\\\\"])*"|\S+/', $text, $matches); print_r($matches); 

这将产生:

 Array ( [0] => Array ( [0] => Lorem [1] => ipsum [2] => "dolor sit amet" [3] => consectetur [4] => "adipiscing \"elit" [5] => dolor ) ) 

正如你所看到的,它也包含了引用string中的转义引号。

编辑

简单的解释:

 " # match the character '"' (?: # start non-capture group 1 \\ # match the character '\' . # match any character except line breaks | # OR [^\\"] # match any character except '\' and '"' )* # end non-capture group 1 and repeat it zero or more times " # match the character '"' | # OR \S+ # match a non-whitespace character: [^\s] and repeat it one or more times 

如果匹配%22而不是双引号,你可以这样做:

 preg_match_all('/%22(?:\\\\.|(?!%22).)*%22|\S+/', $text, $matches); 

str_getcsv()会更容易。

 $test = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor'; var_dump(str_getcsv($test, ' ')); 

给你

 array(6) { [0]=> string(5) "Lorem" [1]=> string(5) "ipsum" [2]=> string(14) "dolor sit amet" [3]=> string(11) "consectetur" [4]=> string(15) "adipiscing elit" [5]=> string(5) "dolor" } 

你也可以试试这个多重爆炸function

 function multiexplode ($delimiters,$string) { $ready = str_replace($delimiters, $delimiters[0], $string); $launch = explode($delimiters[0], $ready); return $launch; } $text = "here is a sample: this text, and this will be exploded. this also | this one too :)"; $exploded = multiexplode(array(",",".","|",":"),$text); print_r($exploded); 

在某些情况下,很less有人知道token_get_all()可能是有用的:

 $tokens = token_get_all("<?php $text ?>"); $separator = ' '; $items = array(); $item = ""; $last = count($tokens) - 1; foreach($tokens as $index => $token) { if($index != 0 && $index != $last) { if(count($token) == 3) { if($token[0] == T_CONSTANT_ENCAPSED_STRING) { $token = substr($token[1], 1, -1); } else { $token = $token[1]; } } if($token == $separator) { $items[] = $item; $item = ""; } else { $item .= $token; } } } 

结果:

 Array ( [0] => Lorem [1] => ipsum [2] => dolor sit amet [3] => consectetur [4] => adipiscing elit [5] => dolor ) 

我来到这里的时候遇到了类似这样的复杂的string分割问题,但是这里没有任何答案完全符合我的要求 – 所以我写了自己的。

我在这里发布它,以防万一它对别人有帮助。

这可能是一个非常缓慢和低效率的方式 – 但它对我有用。

 function explode_adv($openers, $closers, $togglers, $delimiters, $str) { $chars = str_split($str); $parts = []; $nextpart = ""; $toggle_states = array_fill_keys($togglers, false); // true = now inside, false = now outside $depth = 0; foreach($chars as $char) { if(in_array($char, $openers)) $depth++; elseif(in_array($char, $closers)) $depth--; elseif(in_array($char, $togglers)) { if($toggle_states[$char]) $depth--; // we are inside a toggle block, leave it and decrease the depth else // we are outside a toggle block, enter it and increase the depth $depth++; // invert the toggle block state $toggle_states[$char] = !$toggle_states[$char]; } else $nextpart .= $char; if($depth < 0) $depth = 0; if(in_array($char, $delimiters) && $depth == 0 && !in_array($char, $closers)) { $parts[] = substr($nextpart, 0, -1); $nextpart = ""; } } if(strlen($nextpart) > 0) $parts[] = $nextpart; return $parts; } 

用法如下。 explode_adv需要5个参数:

  1. 打开块的字符数组 – 例如[(等)
  2. closures块的字符数组 – 例如])
  3. 切换块的字符数组 – 例如"'
  4. 应该导致拆分到下一部分的字符数组。
  5. 要处理的string。

这种方法可能有缺陷 – 编辑是受欢迎的。