2

我有一个如下字符串(示例中的字母可以是数字或文本,可以是大写或小写或两者。如果一个值是一个句子,它应该在单引号之间):

$string="a,b,c,(d,e,f),g,'h, i j.',k";

我怎样才能爆炸得到以下结果?

Array([0]=>"a",[1]=>"b",[2]=>"c",[3]=>"(d,e,f)",[4]=>"g",[5]=>"'h,i j'",[6]=>"k")

我认为使用正则表达式将是一个快速且干净的解决方案。任何想法?

编辑: 这是我到目前为止所做的,对于括号之间有很长部分的字符串来说,这非常慢:

$separator="*"; // whatever which is not used in the string
$Pattern="'[^,]([^']+),([^']+)[^,]'";
while(ereg($Pattern,$String,$Regs)){
    $String=ereg_replace($Pattern,"'\\1$separator\\2'",$String);
}

$Pattern="\(([^(^']+),([^)^']+)\)";
while(ereg($Pattern,$String,$Regs)){
    $String=ereg_replace($Pattern,"(\\1$separator\\2)",$String);
}

return $String;

这将替换括号之间的所有逗号。然后我可以用逗号分解它并$separator用原来的逗号替换。

4

1 回答 1

6

您可以使用 preg_match_all 完成这项工作

$string="a,b,c,(d,e,f),g,'h, i j.',k";

preg_match_all("~'[^']+'|\([^)]+\)|[^,]+~", $string, $result);
print_r($result[0]);

解释:

诀窍是在括号之前匹配括号,

~          Pattern delimiter
'
[^']       All charaters but not a single quote
+          one or more times 
'
|          or
\([^)]+\)  the same with parenthesis
|          or
[^,]+      Any characters except commas one or more times
~

请注意,由于“自动占有” ,量词 in [^']+'、 in[^)]+\)以及 in[^,]+都会在编译时自动优化为所有格量词。前两个是因为字符类不包含下一个字符,最后一个是因为它位于模式的末尾。在这两种情况下,最终的回溯都是不必要的。

如果您有多个分隔符(如引号)(打开和关闭相同),您可以使用捕获组这样编写模式:

$string="a,b,c,(d,e,f),g,'h, i j.',k,°l,m°,#o,p#,@q,r@,s";

preg_match_all('~([\'#@°]).*?\1|\([^)]+\)|[^,]+~', $string, $result);
print_r($result[0]);

解释:

(['#@°])   one character in the class is captured in group 1
.*?        any character zero or more time in lazy mode 
\1         group 1 content

使用嵌套括号:

$string="a,b,(c,(d,(e),f),t),g,'h, i j.',k,°l,m°,#o,p#,@q,r@,s";

preg_match_all('~([\'#@°]).*?\1|(\((?:[^()]+|(?-1))*+\))|[^,]+~', $string, $result);
print_r($result[0]);
于 2013-05-10T07:00:51.947 回答