[英]Regex: there's a regex inside
我正在深入正则表达式的阴暗面。 我需要解析这个:
{{word(a|b|c)|word$1}}
{{word(s?)|word$1}}
{{w(a|b|c)ord(s?)|w$1ord$2}}
您可能已经注意到,它是一个搜索和替换方案,其中包含正则表达式。 Wikimedia引擎做得很好,但是我找不到它的作用: 就在这里 。
我只需要将第一部分和第二部分分成两个单独的变量即可。 例如:
preg_match(REGEX, "{{word(a|b|c)|word$1}}", $result) // Applying REGEX on this
echo $result[1] // word(a|b|c)
echo $result[2] // word$1
你会怎么做? 就像正则表达式中的正则表达式,我完全迷失了...
您可以使用以下内容匹配零件:
{{((?:(?!}}).)+)\|([^|]+?)}}
请注意,如果您允许任意PCRE正则表达式,那么可以构建一些非常复杂和缓慢的模式,可能允许在您的站点上进行简单的DoS攻击。
这实际上取决于嵌套的深度,但是您可以将其拆分为|
,小心不要分开任何|
在括号内。 我想这是简单的方法:
$str = 'word(a|b|c)|word$1'; // Trim off the leading and trailing {{ and }}
$items = explode('|', $str);
$realItems = array();
for($i = 0; $i < count($items); $i++) {
$realItem = $items[$i];
while(substr_count($realItem, '(') > substr_count($realItem, ')')) {
// Glue them together and skip one!
$realItem .= '|' . $items[++$i];
}
$realItems[] = $realItem;
}
现在$realItems[]
包含2-4个键值,您可以将它们简单地传递到preg_replace
; 它会为你做所有的工作。
实际上并不难。
问题是,替换字符串将只包含一个逃脱|
,即\\|
。
对于其中一个场合, .*
实际上在这里很有用。
执行: preg_match("^{{(.*)\\|([^|]+(?:\\\\\\|[^|]*)*)}}$", $result);
,这应该做您想要的。
这里的诀窍是第二组:它是normal* (special normal*)*
模式,其中normal
是[^|]
(除了管道之外的任何东西),而special
是\\\\\\|
(反斜杠后跟管道)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.