为什么某些正则表达式命令对不同字符的“\”有相反的解释?

为什么某些正则表达式命令对不同字符的“\”有相反的解释?

以这个命令为例:

find . -regex ".*\.\(cpp\|h\)"

这将找到目录中的所有 .h 和 .cpp 文件。句号字符“.”在正则表达式中通常表示“任何字符”。要使其仅匹配实际句点,必须使用反斜杠字符“\”对其进行转义。

在这种情况下,给定一个具有特殊含义的字符,您必须对其进行转义才能获取它所代表的实际字符。

现在,取括号和“或”栏,分别为字符“(”、“)”和“|”。它们也有特殊的含义,用于对正则表达式进行分组。但是,为了获得特殊含义,必须使用反斜杠对字符进行转义!如果没有反斜杠,这些字符具有其所代表的实际字符的含义。

为什么是‘.’与“(”、“)”和“|”的处理方式不同吗?

答案1

答案确实是“只是因为”。有一大堆不同的正则表达式语法,虽然它们具有相似的外观并且通常基础知识是相同的,但它们在细节上有所不同。

从历史上看,每个工具都有自己的新实现,做作者认为最好的事情。在使字符变得特殊(有转义和不转义)之间有一个平衡——太多的“自然特殊”的字符,你最终不得不一直转义它们只是为了匹配它们;或者,相反,您最终需要一堆转义符才能使用常见的正则表达式语法,例如 () 分组。每个编写程序的人都根据他们的程序所匹配的需求、他们认为正确的方法以及月相来决定如何做。

POSIX 尝试标准化,它定义了“基本正则表达式“ 和 ”扩展正则表达式“。令人惊奇的是,这些工作在以下方面是相互倒退的\——有时,但并不具有完美的一致性。

Perl 正则表达式已成为另一个事实上的标准,原因有二:首先,它们非常灵活和强大,其次,它们其实很理智,使用诸如“\ 总是转义非字母数字字符”之类的约定。

GNU Find 有一个-regextype选项,您可以在其中更改所使用的正则表达式语法。遗憾的是,“perl”不是一个选项,至少在我的 find 版本中是这样。 (GNU 的默认值是“emacs”,这并不奇怪,语法是记录在这里.)

相关内容