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个参数:
- 打开块的字符数组 – 例如
[
,(
等) - closures块的字符数组 – 例如
]
,)
等 - 切换块的字符数组 – 例如
"
,'
等 - 应该导致拆分到下一部分的字符数组。
- 要处理的string。
这种方法可能有缺陷 – 编辑是受欢迎的。