忽略引号内字符的explode()函数?

9

有没有人知道一个快速简便的explode()函数,它可以忽略被任意字符(例如引号)包围的分隔符字符?

例如:

my_explode(
  "/", 
  "This is/a string/that should be/exploded.//But 'not/here',/and 'not/here'"
);

应该得到一个包含以下成员的数组:
This is
a string 
that should be 
exploded.

But 'not/here', 
and 'not/here'

事实上,这些字符被包裹在单引号中可以避免它们成为分隔符。

如果能够处理两个包装字符,将会获得额外的加分。

(not/here)

最好使用本地PHP解决方案,但我认为这样的解决方案不存在!


3个回答

8

str_getcsv($str, '/')

链接页面中有适用于小于5.3版本的使用方法。


那么,传递一个不同的字符作为封闭符。 - Ignacio Vazquez-Abrams
无论如何都不会返回。它返回Array ( [0] => 这是 [1] => 一个字符串 [2] => 应该被 [3] => 分解。 [4] => [5] => 但不是'这里' [6] => 和不是'这里' ) - Gordon
那对我来说像是 PHP 的一个 bug。 - Ignacio Vazquez-Abrams
1
str_getcsv只会识别出现在分割部分开头的封闭字符(即字符串开头或分隔符之后)。这不是一个错误(它可以正确处理CSV),但对于这个问题来说并不适用。 - Brilliand
1
str_getcsv($str,'/',"'"); 第三个参数是封闭符。 - kanchan

5

使用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];
}

(请注意,我把所有的变量都放在方括号中,以最小化需要转义的内容 - 在方括号之外,有大约两倍的特殊字符。)
如果您想使用]作为引用,则可能想要使用[作为相应的引用,但我会把添加该功能留给读者作为练习。 :)

边缘情况:如果引号不平衡,该函数将丢弃足够的引号使它们平衡。 - Brilliand
我刚刚了解到preg_quote函数-这可能是在正则表达式中转义字符的更好方法。 - Brilliand

0

谢谢@greg0ire,这看起来不错,但还需要一些工作。我会尝试用我薄弱的正则表达式知识按照我的需求进行更改。 - Pekka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接