0

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

  1. //.*?\n|//.*$|\s+|.(2场比赛→截图
  2. //.*?(?:\n|$)|\s+|.(3场比赛→截图

背景

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

它的核心是以下正则表达式:

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

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

// first line
// last line

我用这个正则表达式替换//.*?$//.*?\n直接放在 EOF 之前的行注释(没有换行符)将不匹配,而是将其分解为//依此类推。所以我寻找正确的方式来正确表达交替。我发现两个在 Notepad++ 和 winGrep 中表现不同但在 Perl 中相同的正则表达式:

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

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

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

可以在 Notepad++(7.7.1 32 位)和 grepWin(1.9.2 64 位)中观察到。在 Perl 中,我将正则表达式放在 和 之间m@()@mg两者都有 2 个匹配项。

4

1 回答 1

0

Windows 换行剖析

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

在记事本和 grepWin 中,不执行此翻译。所以//.*?(?:\n|$)从不消耗换行符序列,而是在正则表达式引擎匹配的开始处(在e和之间)停止,输入中的剩余部分;然后匹配整个换行序列 ( )。\r$\r\s+\r\n

在此处输入图像描述

//.*?\n另一方面,将\ra 与 a匹配.,然后将\n.

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

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

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

于 2019-08-19T10:03:40.877 回答