在Notepad ++中通过正则表达式匹配单行注释

时间:2019-08-14 13:07:45

标签: regex notepad++ newline regex-alternation

为什么这两个正则表达式在Notepad ++中产生不同的结果?

  1. //.*?\n|//.*$|\s+|.(2个匹配→ screenshot
  2. //.*?(?:\n|$)|\s+|.(3个匹配→ screenshot

背景

我正在用Perl为Delphi写一个原始的词法分析器。目的是提取单词(标识符和关键字),因此不需要正确识别所有类型的标记。

其核心是以下正则表达式:

\{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?$|'([^']|'')*?'|\s+|.

我偶然发现行尾没有被行注释占用。所以我很好奇我是否可以修改正则表达式,以便将完全由行注释组成的两个连续行计为2个“令牌”。

// first line
// last line

我将//.*?$替换为//.*?\n,但是使用此正则表达式,在EOF之前(没有换行符)的行注释将不匹配,而是分成/,{{ 1}},依此类推。因此,我寻找了正确表达替换的正确方法。我发现两个正则表达式在Notepad ++和winGrep中表现不同,但在Perl中表现相同:

实际差异已经在介绍性问题中显示:

  1. /(上述示例源中有2个匹配项)

  2. \{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?\n|//.*?$|'([^']|'')*?'|\s+|.(上述示例源中有3个匹配项)

在Notepad ++(7.7.1 32位)和grepWin(1.9.2 64位)中可以看到它。在Perl中,我将正则表达式放在\{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?(?:\n|$)|'([^']|'')*?'|\s+|.m@(之间,两者都有2个匹配项。

1 个答案:

答案 0 :(得分:0)

Windows换行符剖析

观察到的Perl与外部工具之间的差异是由\r\n\n之间的差异引起的。如果您在Perl中读取文本文件,则换行符(序列)将转换为{em>一个字符的\n,因此\n会将此字符匹配为换行符。

在记事本和grepWin中,不执行此翻译。因此//.*?(?:\n|$)从不使用换行符序列,而是从它的开始处停止(就在e\r之间),其中正则表达式引擎与$匹配,\r保留在输入中; \s+然后匹配整个换行序列(\r\n)。

enter image description here

另一方面,

//.*?\n\r.进行匹配,然后将\n与之匹配。

如果您将外部工具的模式中的换行符更改为\r\n,则两种选择都会给出两个匹配项:

  • //.*?\r\n|//.*$|\s+|.

  • //.*?(?:\r\n|$)|\s+|.