为什么只有)是特殊字符而不是}或]?

时间:2018-09-20 19:04:10

标签: regex

我正在阅读Jan Goyvaerts' "Regular Expressions: The Complete Tutorial and Reference"来修饰我的正则表达式。

在第二章中,Jan专门介绍了“特殊字符:”

  

特殊字符

     

由于我们要做的不只是搜索文字文本,我们还需要保留某些字符以供特殊使用。在本教程讨论的regex风格中,有12个具有特殊含义的字符:反斜杠\,脱字符^,美元符号$,句点或点。,竖线或竖线符号|,问号?,星号或星号*,加号+,左括号(,右括号),方括号[和大括号{”,这些特殊字符通常称为“元字符”。单独使用时,大多数都是错误。

     

(重点是我的)

我知道只有方括号和大括号是特殊的,因为如果没有前面的开括号,则大括号或方括号显然是字面值。 但是,如果另外两个非闭合圆括号,Jan为什么要指定闭合括号 是一个特殊字符呢?

4 个答案:

答案 0 :(得分:1)

following paragraphs给出答案。不过,我引用的是Jan的网站,而不是本书:

  

如果您忘记在不使用特殊字符的情况下转义该特殊字符   允许,例如+1中,那么您将收到一条错误消息。

     

大多数正则表达式都将花括号{当作文字   字符,除非它是像a{1,3}这样的重复运算符的一部分。   因此,尽管您通常不需要使用反斜杠将其转义,   可以根据需要这样做。但是也有一些例外。   Java要求   字面量大括号要逃脱。   Boost和   std::regex   要求所有大括号都转义。

     

]character classes之外的文字。   字符类内部适用不同的规则。这些在   有关字符类的主题。同样,也有例外。   std::regex和   Ruby需要关闭   方括号甚至在字符类之外也可以转义。

似乎他使用“需要逃脱”作为“特殊字符”的定义,与)不同的是,]}字符不需要在< em>大多数口味。

也就是说,您也可以将它们称为特殊字符。绝对是最好的习惯,总是逃避它们,并且\]\}的含义除了字面意义的]}以外,什么也没有。

另一方面,它们只有在特定的(解析)上下文中才具有特殊含义,即分别遵循[{时。也有类似的情况::=><!#'&,在特定上下文中都具有非字面意义,我们通常也不会称这些“特殊字符”。

尽管我们可以对)说同样的话,但是几乎没有任何味道允许它在组之外单独出现,因为成对的括号总是需要匹配的。它的唯一用法是在特殊情况下使用,因此)被认为是特殊字符。

答案 1 :(得分:1)

在正则表达式中的每个位置,无论引擎和其标准如何,都应转义括号以表示文字字符。甚至是右括号。但是,它不适用于POSIX regular expressions

  

)<right-parenthesis>与前面的<left-parenthesis>匹配时,在括号表达式之外都应是特殊的。

但是有趣的部分是POSIX对于右括号有一个单独的定义,有时它应该被视为特殊字符。 }]没有它。

为什么其他引擎不遵循此规则?

称它为实施特有性或历史原因,与PCRE source code中所评论的Perl有关:

/* It appears that Perl allows any characters whatsoever, other than
a closing parenthesis, to appear in arguments, so we no longer insist on
letters, digits, and underscores. */

在更高级的引擎中,将所有特殊簇都视为圆括号作为特殊字符,似乎比实现POSIX标准要便宜得多。

答案 2 :(得分:1)

简短回答

我的书中的正则表达式风格不需要转义}](JavaScript字符类中的]除外)。因此,我因为我希望正则表达式中的反斜杠尽可能少。如果您发现正则表达式更清晰,则可以逃脱它们。

完整答案

首先,任何学习正则表达式的人都需要了解限定符的重要性“在本教程讨论的正则表达式中...” 您不能在不说明正则表达式的情况下讨论正则表达式(s)您正在谈论。

我写的东西确实符合我的书(2006年版)所讨论的口味。在这些风格中,)被视为关闭组的令牌。如果在没有相应的(的情况下使用,则会出现语法错误。因此,)单独使用时具有特殊的含义。

}单独使用时没有特殊含义。您永远不需要用这些口味逃脱它。如果您想从字面上匹配{7}{7,42}之类的东西,则只需要转义开头的{。如果您想说}之所以特殊是因为它有时具有特殊的含义,那么您将不得不对,说同样的话,在相同情况下它会变得特别。

在这些正则表达式中,

]在字符类之外没有特殊含义。您无需在角色类之外进行转义。您引用的段落没有讨论字符类中的特殊字符。这是完全不同的列表(\]^-),将在下一章中进行讨论。

现在为什么:大多数正则表达式已经有很多反斜杠。我的首选样式是根据需要转义尽可能少的字符。所以我从不逃脱}。使用JavaScript时,我在字符类中转义了],因为这是唯一的方法。但是我将]放在其他字符中,放在字符类的开头或否定的插入号之后,因此我不需要对其进行转义。我的教材讲授了这种风格。当我的产品RegexBuddy或RegexMagic转换或生成正则表达式时,它们还会根据需要使用尽可能少的反斜杠。

我经常看到刚接触正则表达式的人不必要地转义诸如"'/之类的字符,因为当正则表达式被引用为源代码文字时,它们需要被转义在某些编程语言中。但是,正则表达式本身并不需要将其转义。

我什至看到人们逃脱了<>之类的字符。这是一个坏习惯,因为在某些正则表达式中,\<\>是单词边界。这包括PCRE的最新版本(但不包括2006年最新的PCRE)。

但是,如果您发现将未转义的}]用作文字令人困惑,则可以在正则表达式中随意转义它们。除了<>以外,我在书中讨论的所有样式都允许您转义任何标点符号字符以按字面值匹配,即使该字符本身已经是一个字面值。

因此,有人说}]是正则表达式中的特殊字符,如果“特殊字符”的意思是“具有其自身含义或与...其他字符”。但是该列表还将包括,(量化器),:(非捕获组),-(模式修改器),!(负向环视),{{1 }}(向后看)和<(字符类范围)。

但是,如果“特殊字符”的意思是“具有特殊含义的字符”,那么-}就不会包含在我的书中所涉及的口味列表中。

答案 3 :(得分:0)

从实验看来,与myscript.py不同,字符)]仅在相应的开头}[具有被满足。


尽管IMO可以将相同的规则应用于{,但事实就是这样。

这可能是由于解析器的编写方式所致:括号可以嵌套,因此需要检查平衡性,而括号/花括号只是标记。 (例如,)是有效的类定义。[[]也是有效的模式,但可以理解为[[]]。)