扩展正则表达式如何解释\\ n和\\\ n?

时间:2011-08-06 13:44:14

标签: regex escaping lexer

  

在ERE中,反斜杠字符(\,\ a,\ b,\ f,\ n,        \ r,\ t,\ v)被认为是开始转义序列。

然后我看到\\n[\\\n],虽然\\n[\\\n]这里意味着\后面跟着新行,但我可以猜到,但我是被解释这样的序列的确切过程混淆了需要多少\个?

更新

我对编程语言中的正则表达式没有问题所以请在the lexer内创建上下文。

[root@ ]# echo "test\
> hi"

2 个答案:

答案 0 :(得分:1)

这取决于编程语言及其字符串处理选项。

例如,在Java字符串中,如果字符串中需要文字反斜杠,则需要将其加倍。因此,正则表达式\n必须写为"\\n"。如果你计划使用正则表达式匹配反斜杠,那么你需要将它转义两次 - 一次用于Java的字符串处理程序,一次用于正则表达式引擎。因此,要匹配\,正则表达式为\\,相应的Java字符串为"\\\\"

许多编程语言都有特殊的“逐字”或“原始”字符串,您无需转义反斜杠。因此,正则表达式\n可以写为普通的Python字符串"\\n",也可以写成Python原始字符串r"\n"。 Python字符串"\n"是实际的换行符。

这可能会变得令人困惑,因为有时候无法避免反斜杠的工作。例如,Python字符串"\d\n"恰好用作匹配数字的正则表达式,后跟换行符。这是因为\d不是Python字符串中可识别的字符转义序列,因此它保持为文字\d并以此方式提供给正则表达式引擎。 \n被转换为实际的换行符,但这恰好匹配了测试正则表达式的字符串中的换行符。

但是,如果您忘记转义生成的序列是有效字符转义序列的反斜杠,则会发生错误。例如,正则表达式\bfoo\b匹配整个单词foo(但它与foo中的foobar不匹配)。如果您将正则表达式字符串写为"\bfoo\b",则字符串处理器会将\b转换为退格字符,因此请求正则表达式引擎匹配<backspace>foo<backspace>,这显然会失败。

解决方案:始终使用逐字符串(例如Python的r"...",.NET的@"...")或使用正则表达式文字(例如JavaScript和Ruby的/.../)。或者使用RegexBuddy自动将正则表达式转换为您语言的特殊格式。

回到你的例子:

  • \\n正则表示“匹配反斜杠,后跟n
  • [\\\n]正则表示“匹配反斜杠或换行符”。

答案 1 :(得分:0)

实际上,由字符串文字指定的regex字符串由两个编译器处理:编程语言编译器和regexp编译器:

    Original  Compiled    Regex compiled
    "\n"      NL          NL
    "\\n"     '\'+'n'     NL
    "\\\n"    '\'+NL      NL
    "\\\\n"   '\'+'\'+'n' '\'+'n'

因此,您必须使用最短格式"\n"

代码示例:

JavaScript:

    'a\nb'.replace(RegExp("\n"),'<br>')
    'a\nb'.replace(RegExp("\\n"),'<br>')
    'a\nb'.replace(RegExp("\\\n"),'<br>')

但不是:

    'a\nb'.replace(/\\\n/,'<br>')

Java:

    System.out.println("a\nb".replaceAll("\n","<br>"));
    System.out.println("a\nb".replaceAll("\\n","<br>"));
    System.out.println("a\nb".replaceAll("\\\n","<br>"));

Python:

    str.join('<br>',regex.split('\n','a\nb'))
    str.join('<br>',regex.split('\\n','a\nb'))
    str.join('<br>',regex.split('\\\n','a\nb'))