这是一系列教育正则表达式文章的第二部分。它显示了前瞻和嵌套引用如何用于匹配非常规语言 n b n 。嵌套引用首先在:How does this regex find triangular numbers?
中引入
其中一个原型非regular languages是:
L = { a
nb
n: n > 0 }
这是所有非空字符串的语言,由一些a
组成,后跟相同数量的b
。此语言的字符串示例包括ab
,aabb
,aaabbb
。
pumping lemma可以将此语言显示为非常规语言。它实际上是一个原型context-free language,可以由context-free grammar S → aSb | ab
生成。
尽管如此,现代正则表达式实现清楚地认识到的不仅仅是常规语言。也就是说,它们不是形式语言理论定义的“规则”。 PCRE和Perl支持递归正则表达式,.NET支持平衡组定义。甚至更少“奇特”的功能,例如反向引用匹配,意味着正则表达式不规则。
但这个“基本”功能有多强大?例如,我们可以用Java正则表达式识别L
吗?我们是否可以组合使用外观和嵌套引用,并且可以使用与String.matches
匹配ab
,aabb
,aaabbb
等字符串?
java.util.regex.Pattern
答案 0 :(得分:131)
答案 1 :(得分:21)
鉴于没有提及PCRE支持递归模式,我只想指出PCRE中描述所讨论语言的最简单,最有效的例子:
/^(a(?1)?b)$/
答案 2 :(得分:11)
如问题所述 - 使用.NET平衡组, a n b n c n 类型的模式d n ... z n 可以轻松匹配
^
(?<A>a)+
(?<B-A>b)+ (?(A)(?!))
(?<C-B>c)+ (?(B)(?!))
...
(?<Z-Y>z)+ (?(Y)(?!))
$
例如:http://www.ideone.com/usuOE
修改强>
对于具有递归模式的通用语言,还有一个PCRE模式,但需要前瞻性。我不认为这是上述内容的直接翻译。
^
(?=(a(?-1)?b)) a+
(?=(b(?-1)?c)) b+
...
(?=(x(?-1)?y)) x+
(y(?-1)?z)
$