1

正则表达式的几种实现方式以微妙的方式彼此不同,这是我尝试使用它们时造成很多混乱的根源。

大多数这些差异包括与字符是否转义相关的语义。这通常是括号的问题,但可以适用于大括号和其他问题。这可能是在其中找到实现的语言或环境的语法的结果。例如,如果$符号表示某种语言中的变量名称,则可以预期以该语言表示的正则表达式将需要将“行尾”锚转义到\$或类似的地方。但在这一点上令人困惑的是你将如何表示一个实际的美元符号。我相信 Perl 通过将正则表达式包裹在正斜杠中来解决这个问题/

同样,特定字符本身也有转义,例如非打印字符,例如\nand \t。然后是看起来相似的通用字符组,例如\d数字、\s空格,\w我刚刚学到的包括下划线和数字。我发现自己多次尝试使用\a“字母”组,但这最终只匹配了铃铛字符 0x07。

很明显,没有简单的一次性解决方案来了解无数正则表达式实现所提供的功能和语法的所有差异,除非有人做所有艰苦的工作并将结果整理成一个井井有条的桌子。就是一个例子,但当然它不包括我自己广泛使用的几个程序,包括vim、、sedNotepad++、Eclipse,信不信由你 MS Word(至少是 2010 版,我怀疑是 2007也有这个,他们称之为“通配符”)也有一个简单的正则表达式实现。

我想我想要的是尽可能地懒惰(在某种意义上),通过尝试想出一种方法来确定任何给定的正则表达式实现,它的“转义设置”是毫无疑问的,通过应用一个(或几个) 查询。

我在想我可以制作一个包含测试用例的文件,以及一个巨大的正则表达式查询,并以某种方式对其进行设计,以便运行它一次将准确地向我展示我随后需要使用的语法,而不会进一步怀疑自己。(而不是必须编辑文件并使用多个查询来找出一段时间后变得非常陈旧的同一件事)。

如果没有其他人试图建造这样一个怪物,我可以自己承担这个任务。如果可能的话。这可能吗?

我试图想出一个例子(这只是为了弄清楚 EOL 锚是$还是\$),但在每种情况下,我都必须使用大量不同的搜索/替换查询来确定程序将如何响应输入。

编辑:我想出了一些使用捕获和回溯的东西。我得再努力一点。

更新:好吧,Notepad++ 没有实现通常由 pipe 表示的 OR 运算符|。Word 的“通配符”也是一个糟糕的替代品,它没有|or *。我相当确定缺少任何正则表达式运算符(联合、连接、星号)意味着它无法生成正则语法,因此排除了这两个。

我可以像这样创建一个输入文件:

$
*
]
EOL

并查询

(\$)|(\*)|(\[)|($)

替换为

escDollar:\1:escStar:\2:escSQBrL:\3:Dollar:\4:

产生结果(假设未转义的括号是组并且未转义的管道是或)

escDollar:$:escStar::escSQBrL::Dollar::
escDollar::escStar:*:escSQBrL::Dollar::
]escDollar::escStar::escSQBrL::Dollar::
EOLescDollar::escStar::escSQBrL::Dollar::

我在vim. 此输出将演示与其旁边指定的每个项目匹配的单个字符,即转义的美元符号项目被视为匹配实际的美元符号字符,而不是最后的非转义美元符号项目。

由于它匹配零个字符,因此很难看到$锚点发生了什么,但为它找到解决方案应该不难。此外,这不是一个常见的错误。我特别担心的是管道和括号以及不同的括号。当您有 4 种不同类型时,您可以使用 2^4 转义和非转义版本的组合。反复试验是可怕的。

这个输出一目了然地解析起来并不难,而且作为脚本的一部分也很容易处理。剩下的一个明显问题是弄清楚是否需要转义括号和管道。因为整个事物的功能取决于它们。

看起来这将需要多个查询。可以通过巧妙设计的反斜杠、括号和管道的混乱来找出初始查询的组合(毕竟只有 4 种可能性),然后根据它选择后续的矩阵生成器查询。

这样的事情表明它可以工作:

(e)
(f)

查询

\((f\))|\|\((e\))

用。。。来代替

\1:\2

会产生:

  • :(e如果转义的括号是组并且转义的管道是或
  • :e)如果 parens 是 group 并且转义管道是 or
  • (f:如果转义的括号是组并且管道是或
  • f):如果 parens 是 group 并且 pipe 是 or

我仍然不太喜欢这个,因为它需要对第二组输入进行第二次查询。设置太多。我可能只制作 4 份“矩阵”的东西。

4

1 回答 1

1

此页面上的表格很好地总结了哪些正则表达式实现中可用的功能:

http://www.regular-expressions.info/refflavors.html

于 2011-09-07T22:49:05.650 回答