PHP爆炸的字符串,但对待引号的话作为一个单词
我怎么能爆炸以下字符串:PHP爆炸的字符串,但对待引号的话作为一个单词
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
)
)
正如你所看到的,这也说明了引号的字符串内转义引号。
编辑
的简短解释:
" # 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);
是否有理由不使用'preg_split'而不是'preg_match_all'?它看起来像一个更自然的国际海事组织。 – prodigitalson 2010-02-04 19:20:08
太棒了!我将不得不研究一下代码以确定发生的事情!感谢 – timofey 2010-02-04 19:21:10
@prodigitalson:没有,使用'使preg_split(...)'你无法解释转义字符。 'preg_match_all(...)'“表现得更像是一个解析器,这是更自然的事情。此外,在使用'使preg_split(...)',你需要提前看各的空间,看看有多少引号是在它前面,使它成为一个'为O(n^2)'操作:对于小没问题字符串,但是当涉及更大的字符串时可能会减少运行时间。 – 2010-02-04 19:31:17
这将更加用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"
}
这适用于我的开发机器,但不适用于我的生产服务器。 : -/ – 2012-03-17 18:22:26
str_getcsv需要PHP 5.3。 – armakuni 2013-08-02 06:18:38
啊为什么我现在才发现这个功能?! – 2015-01-03 07:38:09
您也可以尝试这种多爆炸功能
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);
这个答案很好,但是如果你要求它在空格和引号上拆分,它会在引号内的空格上分开。 – starbeamrainbowlabs 2015-05-20 16:38:54
在某些情况下鲜为人知的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;
}
}
}
Resul TS:
Array
(
[0] => Lorem
[1] => ipsum
[2] => dolor sit amet
[3] => consectetur
[4] => adipiscing elit
[5] => dolor
)
我来到这里有一个类似的复杂的字符串分割的问题,但没有答案在这里也正是我想要的 - 所以我写了我自己。
我在这里发布它,以防万一它对别人有帮助。
这可能是一种非常缓慢且低效的方式 - 但它适用于我。
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个参数:
- 打开块的字符数组 - 例如,
[
,(
等 - 该关闭块字符数组 - 例如
]
,)
等 - 切换块的字符数组 - 例如,
"
,'
等 - 应该导致拆分到下一部分的字符数组。
- 串去努力。
此方法可能存在缺陷 - 欢迎编辑。
这听起来像一个正则表达式的工作 – Earlz 2010-02-04 19:10:01
另请参阅[爆炸()函数,忽略引号内的字符?](http://stackoverflow.com/questions/3264775/an-explode-function-that-ignores-characters -Iside-quotes) – Bergi 2013-09-10 21:43:50