提问人:Pekka 提问时间:7/16/2010 更新时间:12/7/2012 访问量:6854
一个忽略引号内字符的 explode() 函数?
An explode() function that ignores characters inside quotes?
问:
有没有人知道一个快速简便的类似函数,可以忽略包含在一对任意字符(例如引号)中的拆分字符?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解决方案是首选,但我认为不存在这样的事情!
答:
8赞
Ignacio Vazquez-Abrams
7/16/2010
#1
str_getcsv
($str, '/')
链接页面上有一个 <5.3 的配方。
评论
0赞
Ignacio Vazquez-Abrams
7/16/2010
因此,然后传递一个不同的字符作为外壳。
0赞
Gordon
7/16/2010
无所谓。它返回Array ( [0] => This is [1] => a string [2] => that should be [3] => exploded. [4] => [5] => But 'not [6] => here', [7] => and 'not [8] => here' )
0赞
Ignacio Vazquez-Abrams
7/16/2010
对我来说,这闻起来像一个PHP错误。
1赞
Brilliand
12/7/2012
str_getcsv
仅确认出现在拆分部分开头(即字符串开头或分隔符之后)的外壳字符。不是错误(它可以正确处理 CSV),但对这个问题没有好处。
1赞
kanchan
7/26/2016
str_getcsv($str,'/',“'”);第三个参数是外壳。
0赞
greg0ire
7/16/2010
#2
与preg_split非常接近的东西:https://www.php.net/manual/en/function.preg-split.php#92632
它处理多个包装字符和多个分隔符。
评论
0赞
Pekka
7/17/2010
干杯@greg0ire,这看起来不错,但仍需要一些工作。我将尝试用我对正则表达式的薄弱知识来改变它以满足我的需要。
5赞
Brilliand
12/7/2012
#3
这几乎是不可能的,因为你无法从字符串的中间判断你是否在引号之间。但是,可以完成这项工作。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];
}
(请注意,我将所有变量都保留在方括号之间,以尽量减少需要转义的内容 - 在方括号之外,特殊字符的数量大约是方括号的两倍。
如果你想用 ] 作为引号,那么你可能想用 [ 作为相应的引号,但我会把添加该功能作为读者的练习。 :)
评论
0赞
Brilliand
12/7/2012
边缘情况:如果引号不平衡,此函数将丢弃足够多的引号以使其平衡。
0赞
Brilliand
1/14/2014
我刚刚发现了这个函数 - 这可能是在正则表达式中转义字符的更好方法。preg_quote
下一个:将字节数据编码为数字
评论