我正试图使用php将字符串拆分为数组组件,使用"
或'
作为分隔符。我只想被最外面的绳子分开。这里有四个例子,每个例子都有想要的结果:
$pattern = "?????";
$str = "the cat 'sat on' the mat";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
[0] => the cat
[1] => 'sat on'
[2] => the mat
)*/
$str = "the cat '"sat on'" the mat";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
[0] => the cat
[1] => "sat on"
[2] => the mat
)*/
$str = "the '"cat 'sat' on'" the mat";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
[0] => the
[1] => "cat 'sat' on"
[2] => the mat
)*/
$str = "the 'cat '"sat'" on' the mat 'when '"it'" was' seventeen";
$res = preg_split($pattern, $str);
print_r($res);
/*output:
Array
(
[0] => the
[1] => 'cat "sat" on'
[2] => the mat
[3] => 'when "it" was'
[4] => seventeen
)*/
正如你所看到的,我只想按最外面的报价进行拆分,而我想忽略报价中的任何报价。
我为$pattern
找到的最接近的是
$pattern = "/((?P<quot>[''"])[^(?P=quot)]*?(?P=quot))/";
但显然这是行不通的。
您可以将preg_split
与PREG_SPLIT_DELIM_CAPTURE
选项一起使用。正则表达式不如@Jan Turoń的反向引用方法优雅,因为所需的捕获组会混淆结果。
$str = "the 'cat '"sat'" on' the mat the '"cat 'sat' on'" the mat";
$match = preg_split("/('[^']*'|'"[^'"]*'")/U", $str, null, PREG_SPLIT_DELIM_CAPTURE);
print_r($match);
您可以仅使用preg_match
:
$str = "the '"cat 'sat' on'" the mat";
$pattern = '/^([^''"]*)(([''"]).*'3)(.*)$/';
if (preg_match($pattern, $str, $matches)) {
printf("[initial] => %s'n[quoted] => %s'n[end] => %s'n",
$matches[1],
$matches[2],
$matches[4]
);
}
此打印:
[initial] => the
[quoted] => "cat 'sat' on"
[end] => the mat
以下是正则表达式的解释:
/^([^''"]*)
=>将初始位放置到第一个捕获组中的第一个引号(单引号或双引号)(([''"]).*'3)
=>在'' 2中捕获从初始引号(单引号或双引号)(在'' 3中捕获)到结束引号(必须与开头引号类型相同,因此为'' 3)的对应文本。regexp本质上是贪婪的,这一事实有助于从第一个引号到最后一个引号,无论里面有多少引号(.*)$/
=>捕获直到'' 4中结束
另一个使用preg_replace_callback 的解决方案
$result1 = array();
function parser($p) {
global $result1;
$result1[] = $p[0];
return "|"; // temporary delimiter
}
$str = "the 'cat '"sat'" on' the mat 'when '"it'" was' seventeen";
$str = preg_replace_callback("/([''"]).*''1/U", "parser", $str);
$result2 = explode("|",$str); // using temporary delimiter
现在您可以使用array_map
压缩这些阵列
$result = array();
function zipper($a,$b) {
global $result;
if($a) $result[] = $a;
if($b) $result[] = $b;
}
array_map("zipper",$result2,$result1);
print_r($result);
结果是
[0] => the
[1] => 'cat "sat" on'
[2] => the mat
[3] => 'when "it" was'
[4] => seventeen
注意:我最好创建一个类来完成这一壮举,这样就可以避免全局变量。
您可以在preg_match_all
中使用反向引用和非自由修饰符
$str = "the 'cat '"sat'" on' the mat 'when '"it'" was' seventeen";
preg_match_all("/([''"])(.*)''1/U", $str, $match);
print_r($match[0]);
现在你有了最外面的报价部件
[0] => 'cat "sat" on'
[1] => 'when "it" was'
你可以用substr
和strpos
(一种黑盒溶液)找到字符串的其余部分
$a = $b = 0; $result = array();
foreach($match[0] as $part) {
$b = strpos($str,$part);
$result[] = substr($str,$a,$b-$a);
$result[] = $part;
$a = $b+strlen($part);
}
$result[] = substr($str,$a);
print_r($result);
这是的结果
[0] => the
[1] => 'cat "sat" on'
[2] => the mat
[3] => 'when "it" was'
[4] => seventeen
如果引号位于字符串的开头/末尾,只需去掉最终的空头/尾元素。