regex - 在 Notepad++ 中通过正则表达式匹配单行注释
问题描述
为什么这两个正则表达式在 Notepad++ 中产生不同的结果?
背景
我正在用 Perl 为 Delphi 编写一个原始词法分析器。目的是提取词(标识符和关键字),因此不需要正确识别各种标记。
它的核心是以下正则表达式:
\{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?$|'([^']|'')*?'|\s+|.
我偶然发现行尾没有被行注释占用。所以我很好奇我是否可以修改正则表达式,以便完全由行注释组成的两个连续行被计为 2 个“令牌”。
// first line
// last line
我用这个正则表达式替换//.*?$
了//.*?\n
直接放在 EOF 之前的行注释(没有换行符)将不匹配,而是将其分解为/
,/
依此类推。所以我寻找正确的方式来正确表达交替。我发现两个在 Notepad++ 和 winGrep 中表现不同但在 Perl 中相同的正则表达式:
介绍性问题中已经显示了实际差异:
\{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?\n|//.*?$|'([^']|'')*?'|\s+|.
(上述示例源中有 2 个匹配项)\{[^}]*\}|\(\*([^*]|\*[^\\])*?\*\)|[A-Za-z_]\w*|\d+|//.*?(?:\n|$)|'([^']|'')*?'|\s+|.
(上述示例源中的 3 个匹配项)
可以在 Notepad++(7.7.1 32 位)和 grepWin(1.9.2 64 位)中观察到。在 Perl 中,我将正则表达式放在 和 之间m@(
,)@mg
两者都有 2 个匹配项。
解决方案
Windows 换行剖析
Perl 和外部工具之间观察到的差异是由 和 之间的差异引起\r\n
的\n
。如果您在 Perl 中读取文本文件,则换行符(序列)被翻译成一个\n
字符,因此将此字符匹配为换行符。\n
在记事本和 grepWin 中,不执行此翻译。所以//.*?(?:\n|$)
从不消耗换行符序列,而是在正则表达式引擎匹配的开始处(在e
和之间)停止,输入中的剩余部分;然后匹配整个换行序列 ( )。\r
$
\r
\s+
\r\n
//.*?\n
另一方面,将\r
a 与 a匹配.
,然后将\n
.
如果您将模式中的换行符更改\r\n
为外部工具,则两种选择都会给出两个匹配项:
//.*?\r\n|//.*$|\s+|.
//.*?(?:\r\n|$)|\s+|.
推荐阅读
- react-native - 如何实现此功能
- macos - Cytoscape 卡塔利娜
- javascript - 如何从数组中仅获取经度和纬度
- spring - 找不到“org.springframework.data.redis.cache.RedisCacheManager”类型的bean
- php - 如何在模态数据表中获取隐藏的 ID 值
- xaml - 如何创建一个简单的布局,如具有背景和不透明度的 TextBlock?
- azure - Azure 数据工厂映射数据流 VS SSIS
- widget - 问题:在 Hybris 后台向导中单击图标时未打开
- c# - 如何处理 System.InvalidOperationException: DataReader.GetFieldType(13)?(再次)
- azure-sql-database - 如何将 azure 分析服务与 azure sql db 连接以获取 250GB 表大小数据?