如何修改正则表达式以排除与双引号包围的短语中包含的冒号匹配?
How to modify a regex to exclude matching against a colon contained in a phrase surrounded by double quotes?
这是我当前的正则表达式(用于解析 iCal 文件):
/([^:]+)[:|(;)]([\w\W]*)/
使用preg_match()
的当前输出是这样的:
//Output 1
Array
(
[0] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London":20150601T073000
[1] => DTEND;TZID="Greenwich Mean Time
[2] => Dublin, Edinburgh, Lisbon, London":20150601T073000
)
我想修改我的正则表达式以输出这个(即忽略冒号,如果它是用双引号括起来的短语的一部分 - 我想我需要回顾一下,而且永远只能找到一个冒号,因为它是分隔符):
//Output 2
Array
(
[0] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London":20150601T073000
[1] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London"
[2] => 20150601T073000
)
正则表达式中的分号在那里,因为有时我要查找的冒号可能在下一行,因为定义了多个属性 (;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London"
),所以在这种情况下,我在分号处打断。有关信息,一次一行读取 iCal 文件。
(.*?)(?::(?=(?:[^"]*"[^"]*")*[^"]*$)|;(?=[^:]*$))([\w\W]*)
您可以尝试 this.See 演示。
您需要一个基于 SKIP-FAIL trick 的正则表达式,它可以安全地匹配其他模式之外的模式。但是,我找不到 1-regex 解决方案:(。您可以使用主要的解决方案来匹配引号字符串外的冒号,如果它无法为您获取超过 1 个元素的数组,请使用另一个:
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|:
和
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|;
"(?:[^"](?:\.[^"]+)?)+"
将安全地匹配任何转义实体(如果有)。
$re = '#"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|:#';
$str = "DTEND;TZID=\"Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London\":20150601T073000";
//$str = "DTEND;TZID=\"Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London\";20150601T07300001T073000";
$arr = preg_split($re, $str);
if (count($arr)>1){
print_r($arr);
}
else {
$re2 = '#"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|;#';
$arr2 = preg_split($re2, $str);
if (count($arr2)>1){
print_r($arr2);
}
else {
echo "No matches";
}
}
再试一次(不确定):
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|(?!.*:);(?=[^:]*$)|(?!.*;):(?=[^;]*$)
这是我当前的正则表达式(用于解析 iCal 文件):
/([^:]+)[:|(;)]([\w\W]*)/
使用preg_match()
的当前输出是这样的:
//Output 1
Array
(
[0] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London":20150601T073000
[1] => DTEND;TZID="Greenwich Mean Time
[2] => Dublin, Edinburgh, Lisbon, London":20150601T073000
)
我想修改我的正则表达式以输出这个(即忽略冒号,如果它是用双引号括起来的短语的一部分 - 我想我需要回顾一下,而且永远只能找到一个冒号,因为它是分隔符):
//Output 2
Array
(
[0] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London":20150601T073000
[1] => DTEND;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London"
[2] => 20150601T073000
)
正则表达式中的分号在那里,因为有时我要查找的冒号可能在下一行,因为定义了多个属性 (;TZID="Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London"
),所以在这种情况下,我在分号处打断。有关信息,一次一行读取 iCal 文件。
(.*?)(?::(?=(?:[^"]*"[^"]*")*[^"]*$)|;(?=[^:]*$))([\w\W]*)
您可以尝试 this.See 演示。
您需要一个基于 SKIP-FAIL trick 的正则表达式,它可以安全地匹配其他模式之外的模式。但是,我找不到 1-regex 解决方案:(。您可以使用主要的解决方案来匹配引号字符串外的冒号,如果它无法为您获取超过 1 个元素的数组,请使用另一个:
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|:
和
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|;
"(?:[^"](?:\.[^"]+)?)+"
将安全地匹配任何转义实体(如果有)。
$re = '#"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|:#';
$str = "DTEND;TZID=\"Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London\":20150601T073000";
//$str = "DTEND;TZID=\"Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London\";20150601T07300001T073000";
$arr = preg_split($re, $str);
if (count($arr)>1){
print_r($arr);
}
else {
$re2 = '#"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|;#';
$arr2 = preg_split($re2, $str);
if (count($arr2)>1){
print_r($arr2);
}
else {
echo "No matches";
}
}
再试一次(不确定):
"(?:[^"](?:\.[^"]+)?)+"(*SKIP)(*FAIL)|(?!.*:);(?=[^:]*$)|(?!.*;):(?=[^;]*$)