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

时间:2010-07-16 12:24:50

标签: php string

有人知道一个快速简单的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 个答案:

答案 0 :(得分:7)

str_getcsv ($str, '/')

链接页面上有< 5.3的配方。

答案 1 :(得分:4)

这对于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];
}

(请注意,我将所有变量保留在方括号之间以最小化需要转义的内容 - 在方括号之外,大约有两倍的特殊字符。)

如果您想使用]作为引用,那么您可能希望使用[作为相应的引用,但我会将该功能添加为读者的练习。 :)

答案 2 :(得分:0)

与preg_split非常接近:http://fr2.php.net/manual/en/function.preg-split.php#92632

它处理多个包装器字符和多个分隔符字符。