0

我正在尝试使用 re2c,但它给了我这个正则表达式的语法错误:

(["'])((\\{2})*|(.*?[^\\](\\{2})*))\1

它出什么问题了?这应该匹配双引号或单引号字符串

4

1 回答 1

1

Re2c 与大多数扫描仪生成器一样,仅实现可以在线性时间内实现而无需回溯的正则表达式原语。因此,它不实现反向引用、捕获(尽管您可以在正则表达式中插入标记标记)或非贪婪匹配。(从技术上讲,非贪婪匹配可以在线性时间内实现。但要正确执行有点棘手。)

正则表达式中的反向引用实际上只是一个缩写,因为它只能采用两个值:它是["][']. 将这两种选择分开也可以很容易地避免非贪婪匹配的需要:

  1. 如果您不允许字符串中的换行符:

    ["]([^"\\\n]|\\.)*["]|[']([^'\\\n]|\\.)*[']
    
  2. 如果仅在转义字符串中允许换行符:

    ["]([^"\\\n]|\\(.|\n))*["]|[']([^'\\\n]|\\(.|\n))*[']
    
  3. 如果您在字符串中的任何位置允许换行符:

    ["]([^"\\]|\\(.|\n))*["]|[']([^'\\]|\\(.|\n))*[']
    

(与 flex 一样,re2c 考虑.匹配除换行符以外的任何字符,而否定字符类确实包含换行符,除非特别提及。因此换行符处理通常需要明确。)

请注意,re2c 确实实现了带引号的文字字符串(如 flex),因此"'是元字符,这是很少出现在正则表达式库中的功能。(与 flex 不同,单引号字符串被接受并视为不区分大小写。在 flex 中,单引号不是元字符。)结果是您必须对它们进行转义以使其成为文字字符;通常的约定是将它们放在一个字符类中,如上所述,而不是使用难以阅读的落木表示。

请阅读re2c patterns 的文档,这可能与您习惯使用的正则表达式库有一些显着差异(或者您在网络搜索中找到了示例)。

于 2020-05-06T14:41:54.830 回答