使用preg_split几乎是不可能的,因为你无法从字符串中间分辨出你是否在引号之间。然而,使用preg_match_all可以完成此任务。
单引号的简单解决方案:
function quoted_explode($subject, $delimiter = ',', $quote = '\'') {
$regex = "(?:[^$delimiter$quote]|[$quote][^$quote]*[$quote])+";
preg_match_all('/'.str_replace('/', '\\/', $regex).'/', $subject, $matches);
return $matches[0];
}
如果你向这个函数传递某些特殊字符(\^-],根据http://www.regular-expressions.info/reference.html),它就会出现各种问题,因此你需要对它们进行转义。下面是一种通用的解决方案,可以分别跟踪多种引号并转义特殊的正则表达式字符:
function regex_escape($subject) {
return str_replace(array('\\', '^', '-', ']'), array('\\\\', '\\^', '\\-', '\\]'), $subject);
}
function quoted_explode($subject, $delimiters = ',', $quotes = '\'') {
$clauses[] = '[^'.regex_escape($delimiters.$quotes).']';
foreach(str_split($quotes) as $quote) {
$quote = regex_escape($quote);
$clauses[] = "[$quote][^$quote]*[$quote]";
}
$regex = '(?:'.implode('|', $clauses).')+';
preg_match_all('/'.str_replace('/', '\\/', $regex).'/', $subject, $matches);
return $matches[0];
}
(请注意,我把所有的变量都放在方括号中,以最小化需要转义的内容 - 在方括号之外,有大约两倍的特殊字符。)
如果您想使用]作为引用,则可能想要使用[作为相应的引用,但我会把添加该功能留给读者作为练习。 :)