【发布时间】:2016-11-11 16:59:54
【问题描述】:
我正在尝试创建一个用于拆分字符串的正则表达式,但不幸的是,我的要求比简单拆分要复杂一些,因此我不能在 PHP 中使用例如 preg_split()。
所以我正在做的是在一个子表达式中匹配我的分隔符(或者更确切地说是其中的一部分),以及在另一个子表达式中匹配它之前的所有内容,并将字符串的结尾视为一个分隔符。 .考虑到这一点,我想出了以下内容:
([^?;]*)(?|\?([0-9]*)|(;)|$)
如您所见,第一个子模式会查找没有任何分号问号的文本块。在此之后,我有一个子模式匹配任何问号与之后的可选数字(存储),或者是分号(存储)或字符串的结尾。
问题是我似乎得到了一个无关紧要的空匹配字符串大小写,如下所示:
$sql = 'CALL foo(?0, ?1, ?2, ?3)';
preg_match_all('/([^?;]*)(?|\?([0-9]*)|(;)|$)/', $sql, $matches);
print_r($matches);
生成如下所示的输出:
Array
(
[0] => Array
(
[0] => CALL insert_host(?0
[1] => , ?1
[2] => , ?2
[3] => , ?3
[4] => )
[5] =>
)
[1] => Array
(
[0] => CALL insert_host(
[1] => ,
[2] => ,
[3] => ,
[4] => )
[5] =>
)
[2] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 3
[4] =>
[5] =>
)
)
注意$matches[0][5]下的空匹配;我本来希望在匹配括号后满足字符串大小写的结尾,导致没有进一步的匹配,但它继续产生另一个匹配,我不知道为什么。
所以我的问题是;为什么这里会产生额外的匹配,我该如何防止它?
注意:我已经考虑过要求字符串大小写的结尾至少有一个字符,但这并不好,因为如果通配符是,我实际上想要一个空结果在字符串的 处,因为我正在尝试模拟拆分函数的行为。例如,如果输入是SELECT ?,我希望匹配SELECT ? 加上一个空字符串。这里的想法是,一旦我处理了任何匹配的分号,我就可以简单地使用implode('?', $matches[1]) 来重现带有数字通配符的语句。
【问题讨论】: