在我完成的工作中,我只需要使用正则表达式几次.然而,在那几次我发现了一种非常强大的表达形式,这使我能够做一些非常有用的事情.
问题是用于正则表达式的语言是错误的 - 完全停止.
从心理学的角度来看,这是错误的 - 使用无实体符号仅为那些具有极端记忆的人提供了有用的参考.虽然根据我的经验和从别人那里学到的语法清晰地阐述了句法规则,但是演绎成功运作的正则表达式在除了最微不足道的情况之外的所有事情中都可能是一件困难的事情.这是可以理解的,因为它是集合论的象征模拟,这是一个相当复杂的事情.
可以证明困难的一件事就是将你正在研究的表达式溶解到它的离散部分.由于语言的性质,如果您不了解其主要目标,则可以通过多种方式阅读一个正则表达式,因此解释其他人的正则表达式很复杂.在自然语言研究中,我认为这被称为语用学.
我想问的问题是 - 这是一个正则表达式编译器吗?或者甚至可以建造一个?
从隐喻的角度来看,可以将正则表达式视为汇编语言 - 有一些相似之处.设计编译器是否可以将更自然的语言 - 更高的语言 - 变成正则表达式?然后在我的代码中,我可以使用头文件中的更高级语言来定义我的正则表达式,并在必要时使用符号引用引用它们.我和其他人可以从我的代码引用头文件,更容易理解我想用我的正则表达式实现的目标.
我知道它可以从逻辑的角度来看,否则计算机是不可能的,但如果你已经阅读了这么远,那么你会考虑投入时间来实现它吗?
1) Perl允许/x
切换正则表达式,使注释和空格能够包含在正则表达式本身中.这使得可以使用缩进来指示块结构,将复杂的正则表达式分布在多行上.
2)如果你不喜欢线条噪声相似的符号本身,那么编写你自己的构建正则表达式的函数并不难.例如Perl:
sub at_start { '^'; } sub at_end { '$'; } sub any { "."; } sub zero_or_more { "(?:$_[0])*"; } sub one_or_more { "(?:$_[0])+"; } sub optional { "(?:$_[0])?"; } sub remember { "($_[0])"; } sub one_of { "(?:" . join("|", @_) . ")"; } sub in_charset { "[$_[0]]"; } # I know it's broken for ']'... sub not_in_charset { "[^$_[0]]"; } # I know it's broken for ']'...
然后例如匹配带引号的字符串(/^"(?:[^\\"]|\\.)*"/
)的正则表达式变为:
at_start . '"' . zero_or_more( one_of( not_in_charset('\\\\"'), # Yuck, 2 levels of escaping required '\\\\' . any ) ) . '"'
使用这种"字符串构建函数"策略有助于将有用的构建块表示为函数(例如,上面的正则表达式可以存储在一个被调用的函数中quoted_string()
,您可能还有其他函数可以可靠地匹配任何数值,电子邮件地址等) .
我从来没有偶然发现过这样的事情.而且我认为这样的东西不会有用.
这种更高级别的语言会非常冗长,我的猜测是你需要很长的语句来提出平均复杂度的正则表达式.
也许你只是没经常使用正则表达式.相信我,我的记忆远非一点一点(甚至是好的),但我很难在制作正则表达式或理解我的同事时遇到问题.
如何用Regex Buddy编写它们并粘贴它生成的描述作为代码注释?
正则表达式(嗯,"真正的"正则表达式,没有现代的东西;)是有限状态机.因此,您可以根据状态,边,输入和可能的输出标签创建描述正则表达式的语法.AT&T 的fsmtools支持这样的东西,但它们远不是日常使用的工具.
XFST中的语言,Xerox有限状态工具包,也更加冗长.
除此之外,我会说,如果你的正则表达式变得过于复杂,你应该转向具有更强表现力的东西.