PHP正则表达式 - 使用元字符作为分隔符

时间:2014-08-20 04:31:12

标签: php regex

所以我一直在阅读php(PCRE)正则表达式doco,我注意到有关分隔符(http://php.net/manual/en/regexp.reference.delimiters.php)的部分说:

“分隔符可以是任何非字母数字,非反斜杠,非空白字符。”

它还讨论了使用括号作为分隔符:

“括号样式分隔符在模式中用作元字符时不需要进行转义,但与其他分隔符一样,它们在用作文字字符时必须进行转义。”

我的问题是,如何使用其他正则表达式元字符作为分隔符,以及将它们用作模式中的元字符?

从我做过的测试来看,不可能使用诸如'|'之类的元字符作为模式中的分隔符和元字符。我想不出有什么理由需要这样做,但我很好奇“正确”的答案是什么。

1 个答案:

答案 0 :(得分:2)

显然,选择一个在模式中具有特殊含义的分隔符可能会导致容易避免的麻烦。所以当然不要这样做。

但为了满足您的好奇心,您的观察结果似乎是正确的,如果您将其用作分隔符,则无法保留角色的特殊含义。让我们浏览相关的PHP source for PCRE functions以了解原因。 (为简单起见,这里省略了一些代码。)

首先,它会跳过它遇到的任何前导空格。

while (isspace((int)*(unsigned char *)p)) p++;

之后,选择delimiter作为字符串中的第一个字符。

delimiter = *p++;

接下来,确定end_delimiter是否与start_delimiter的字符相同,或者它是否是开括号字符的补充(即)补码(]补充[等。回想一下手册如何明确指出支架式字符是以这种方式特殊处理的。

start_delimiter = delimiter;
if ((pp = strchr("([{< )]}> )]}>", delimiter)))
    delimiter = pp[5];
end_delimiter = delimiter;

pp = p;

如果分隔符不是互补括号 - 而是两个字符都相同 - 结尾分隔符被确定为第一个未转义的匹配字符。

while (*pp != 0) {
    if (*pp == '\\' && pp[1] != 0) pp++;
    else if (*pp == delimiter)
        break;
    pp++;
}

一切都很简单,但是一旦找到分隔符,包含的pattern就被确定为两个分隔符之间的逐字符串。

pattern = estrndup(p, pp-p);

因此,您最初在模式中转义的任何字符仍将作为转义字符传输到基础PCRE函数中的模式解析器本身。

re = pcre_compile(pattern, ...

此时,无论您选择哪个分隔符,孤立的模式都是相同的。实际的正则表达式引擎完全无视您的选择。

我希望那就是你所要求的。 : - )