我在这里看到一些评论,提到现代正则表达式超出了常规语言的表达范围。这是怎么回事?
现代正则表达式的哪些特征不规律?例子很有用。
答案 0 :(得分:18)
首先想到的是反向引用:
(\w*)\s\1
(匹配一组单词字符,后跟空格字符,然后是之前匹配的同一组)例如:hello hello
匹配,hello world
不匹配。
此构造不是常规的(即:不能由regular grammar生成)。
Perl兼容RegExp(PCRE)支持的另一个非常规的功能是递归模式:
\((a*|(?R))*\)
这可用于匹配平衡括号和“a”的任意组合(来自wikipedia)
答案 1 :(得分:4)
几个例子:
/my (group)/.match("my group")[1]
将输出“group”。将某些东西存储在一个组中需要一个外部存储器,有限的自动机没有这个存储器。(?<MYGROUP>.)*
可以执行多次捕获“。”在同一组。(?<MYGROUP>test)
推送堆栈,而(?<-MYGROUP>)
弹出堆栈。(?<FIRSTGROUP-LASTGROUP>)
,它弹出LASTGROUP并推送自FIRSTGROUP堆栈上的LASTGROUP索引以来的捕获。这实际上可以用来匹配无限嵌套的结构,这绝对超出了有限自动机的能力。可能存在其他好的例子:-)如果你进一步关注外部堆栈的一些实现细节结合Regex和平衡分组,因此比有限自动机更高阶自动机,我曾经写过两篇关于此的短篇文章( http://www.codeproject.com/KB/recipes/Nested_RegEx_explained.aspx和http://www.codeproject.com/KB/recipes/RegEx_Balanced_Grouping.aspx)。
无论如何 - 有没有 - 我觉得这些额外的东西给普通语言带来的力量很大: - )
溴。的Morten
答案 2 :(得分:3)
确定性或非确定性有限自动机仅识别正则语言,正则语言由正则表达式描述。正则表达式的定义很简单。让 S 为字母表。然后空集,空字符串和 S 的每个元素都是正则表达式(在 S 上)。让 u 和 v 成为正则表达式。然后联合( u | v ),连接( uv )和<(em> u *)< em> u 和 v 是 S 上的正则表达式。该定义很容易扩展到常规语言。没有其他表达式是正则表达式。正如所指出的,一些反向引用就是一个例子。关于常规语言和表达的维基百科页面是很好的参考。
实质上,某些“正则表达式”不是常规的,因为不能构造特定类型的自动机来识别它们。例如,语言
{a ^ i b ^ i : i &lt; = 0}
不规律。这是因为接受自动机需要无限多个状态,但接受常规语言的自动机必须具有有限数量的状态。