regex 为什么正则表达式和字符串文字使用不同的转义序列?

cl25kdpy  于 2023-01-27  发布在  其他
关注(0)|答案(2)|浏览(123)

转义序列的处理在不同的语言以及字符串和正则表达式之间是不同的,例如,在Python中\s转义序列可以用在正则表达式中,但不能用在字符串中,而在PHP中\f换页转义序列可以用在正则表达式中,但不能用在字符串中。
在PHP中,有一个PCRE转义序列(http://php.net/manual/en/regexp.reference.escape.php)的专用页面,但它没有一个专门用于字符串文字的转义序列的官方列表。
作为一个编程的初学者,我担心我可能没有完全理解这个主题的背景和上下文。这些担心是否有效?这是一个其他人都知道的问题吗?

为什么不同的编程语言在处理正则表达式和字符串文字之间的转义序列时会有不同?

j7dteeu8

j7dteeu81#

字符串常量中的转义序列是为了防止编程语言混淆。例如,在许多语言中,字符串常量被表示为引号之间的字符,如下所示

my_string = 'x string'

但是,如果字符串包含引号字符,那么您需要一种方法来告诉编程语言应该将其解释为文本字符

my_string = 'x's string' # this will cause bugs
my_string = 'x\'s string' # lets the programing language know that the internal quote is literal and not the end of the string

我认为大多数编程语言都有相同的字符串转义序列集。
正则表达式是一个不同的故事,你可以认为他们是自己的独立语言,是写为字符串文字。在正则表达式中,一些字符,如句点(.)有特殊的含义,必须转义以匹配其文字对应。而其他字符,当前面有一个反斜杠,使这些字符有特殊的含义。
例如

regex_string = 'A.C'  # match an A, followed by any character, followed by C
regex_string = 'A\.C' # match an A, followed by a period, followed by C
regex_string = 'AsC'  # match an A, followed by s, followed by C
regex_string = 'A\sC'  # match an A, followed by a space character, followed by C

因为正则表达式是它们自己的迷你语言,所以正则表达式中的所有转义序列都可用于普通字符串字面量是没有意义的。

ruarlubt

ruarlubt2#

正则表达式最好被认为是一种语言,它有自己的语法。一些编程语言提供了一种文字语法,专门用于描述正则表达式,但通常正则表达式将从现有的字符串编译。如果你从文字语法创建该字符串,它将使用一组不同的转义序列,因为它是一种不同的东西,用不同的语法创建,在不同的语境中,用不同的语言。这是对这个问题简单直接的回答。
有不同的需要和要求。正则表达式必须能够描述不是单一的,特定的文本序列的东西。字符串字面量显然没有这个问题,但他们确实需要一种方法,比如说,在文本中包括引号。这通常不是正则表达式语法的问题,因为串的内容已经由该点确定。(一些语言具有“正则表达式文字”语法,通常将正则表达式包含在正斜杠中。应该是正则表达式一部分的正斜杠需要转义。)
尽管我明白显而易见的事实(\s表示多个字符,会引起歧义)
对于大多数支持正则表达式的语言来说,多义性实际上并不是一个问题。字符串语法和正则表达式语法经常使用相同的序列来表示不同的内容。例如:\b表示regex语法中的单词边界,但许多语言的字符串语法也使用它来表示退格字符,Unicode代码点8。(除非您认为\s表示“任何空白字符”在字符串文本上下文中没有意义,而仅在regex上下文中有意义--那么当然是的。)
但是请记住--如果正则表达式是从字符串编译而来的,那么首先字符串会被解释,以确定字符串 * 实际上包含了什么 *,然后这个字符串会被用来创建正则表达式。这是 * 独立的步骤,可以而且确实应用了独立的规则 ,所以不存在冲突。
这有时意味着代码必须使用双转义机制:首先是字符串字面量,然后是正则表达式语法。如果你想要一个正则表达式匹配一个字面量反斜杠,你可能最终会在一个字符串字面量中键入 * 四个 * 反斜杠-因为这段代码将创建一个字符串,
实际上只包含 * 两个反斜杠,这反过来又是正则表达式语法所需要的。(一些语言提供了某种“原始”字符串字面量工具来解决这个问题。)

相关问题