有人知道一个快速简单的explode()函数,可以忽略包含在一对任意字符(例如引号)中的拆分器字符吗?
例:
my_explode(
"/",
"This is/a string/that should be/exploded.//But 'not/here',/and 'not/here'"
);
Run Code Online (Sandbox Code Playgroud)
应该导致具有以下成员的数组:
This is
a string
that should be
exploded.
But 'not/here',
and 'not/here'
Run Code Online (Sandbox Code Playgroud)
字符用单引号括起来的事实将使它们不被分割.
可以处理两个包装器字符的解决方案的奖励积分
(not/here)
Run Code Online (Sandbox Code Playgroud)
原生PHP解决方案将是首选,但我不认为这样的事情存在!
这对于 几乎是不可能的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];
}
Run Code Online (Sandbox Code Playgroud)
如果您将某些特殊字符(\^-],根据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];
}
Run Code Online (Sandbox Code Playgroud)
(请注意,我将所有变量保留在方括号之间以最小化需要转义的内容 - 在方括号之外,特殊字符的数量大约是其两倍。)
如果您想使用 ] 作为引号,那么您可能希望使用 [ 作为相应的引号,但我会将添加该功能作为练习留给读者。:)