PHP:用逗号分割字符串,但在大括号或引号之间时不分割吗? [英] PHP: split string on comma, but NOT when between braces or quotes?
问题描述
在PHP中,我有以下字符串:
In PHP I have the following string :
$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO";
我需要将此字符串拆分为以下部分:
I need to split this string into the following parts:
AAA
BBB
(CCC,DDD)
'EEE'
'FFF,GGG'
('HHH','III')
(('JJJ','KKK'),LLL, (MMM,NNN))
OOO
我尝试了多个正则表达式,但是找不到解决方案. 有什么想法吗?
I tried several regexes, but couldn't find a solution. Any ideas?
更新
在处理格式错误的数据,转义的引号等时,我已经决定使用正则表达式并不是真正的最佳解决方案.
I've decided using regex is not really the best solution, when dealing with malformed data, escaped quotes, etc.
由于这里提出了建议,我找到了一个使用解析的函数,我将其重写为适合自己的需求.它可以处理不同类型的括号,并且分隔符和引号也是参数.
Thanks to suggestions made on here, I found a function that uses parsing, which I rewrote to suit my needs. It can handle different kind of brackets and the separator and quote are parameters as well.
function explode_brackets($str, $separator=",", $leftbracket="(", $rightbracket=")", $quote="'", $ignore_escaped_quotes=true ) {
$buffer = '';
$stack = array();
$depth = 0;
$betweenquotes = false;
$len = strlen($str);
for ($i=0; $i<$len; $i++) {
$previouschar = $char;
$char = $str[$i];
switch ($char) {
case $separator:
if (!$betweenquotes) {
if (!$depth) {
if ($buffer !== '') {
$stack[] = $buffer;
$buffer = '';
}
continue 2;
}
}
break;
case $quote:
if ($ignore_escaped_quotes) {
if ($previouschar!="\\") {
$betweenquotes = !$betweenquotes;
}
} else {
$betweenquotes = !$betweenquotes;
}
break;
case $leftbracket:
if (!$betweenquotes) {
$depth++;
}
break;
case $rightbracket:
if (!$betweenquotes) {
if ($depth) {
$depth--;
} else {
$stack[] = $buffer.$char;
$buffer = '';
continue 2;
}
}
break;
}
$buffer .= $char;
}
if ($buffer !== '') {
$stack[] = $buffer;
}
return $stack;
}
推荐答案
代替preg_split
,而是执行preg_match_all
:
$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO";
preg_match_all("/\((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+/", $str, $matches);
print_r($matches);
将打印:
Array
(
[0] => Array
(
[0] => AAA
[1] => BBB
[2] => (CCC,DDD)
[3] => 'EEE'
[4] => 'FFF,GGG'
[5] => ('HHH','III')
[6] => (('JJJ','KKK'), LLL, (MMM,NNN))
[7] => OOO
)
)
正则表达式\((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+
可以分为三个部分:
The regex \((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+
can be divided in three parts:
-
\((?:[^()]|(?R))+\)
,它与括号内的平衡对匹配 -
'[^']*'
匹配带引号的字符串 -
[^(),\s]+
匹配任何不由'('
,')'
,','
或空格字符组成的字符序列
\((?:[^()]|(?R))+\)
, which matches balanced pairs of parenthesis'[^']*'
matching a quoted string[^(),\s]+
which matches any char-sequence not consisting of'('
,')'
,','
or white-space chars
这篇关于PHP:用逗号分割字符串,但在大括号或引号之间时不分割吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!