正则表达式模式产生了意外的结果
我在Notepad++里有这段代码片段
-CaseInsensitive
-ExcludeProperty
-ExpandProperty
-First
-Index
-InputObject
-Last
-Property
-Skip
-SkipIndex
-SkipLast
-Unique
-Wait
我想只删除缩进的行,于是写了这个正则
^(\s+\S+)
我先点了“全部标记”来看看正则引擎能匹配到哪些行,结果是1、4、5、7、9、10、11,符合预期。
然而把这个模式替换为空字符串会把整行都删除。
请问有人能解释一下这之间的矛盾吗?
解决方案
解释
通过对文本反复应用该模式来进行替换。用下面这段内容很容易验证
aaa
然后对 ^a 进行全部替换为空。这通常只会匹配一个。但如果你重复应用替换,第一次之后内容变成
aa
这会再次匹配 ^a,替换后变成
a
再次匹配 ^a,替换后变成空。
同样地,将 ^(\s+\S+) 替换为空会留下一个空行。对于如下输入:
-Foo
-Bar
结果是一行空白,后面跟着另一行文本:
-Bar
然后再次被 ^(\s+\S+) 匹配,因为它是 \n-Bar——行首可以有任意数量的空白(第一行只有一个换行),随后是任意数量的非空白字符(第二行的 -Bar)。这是因为 \s 会吞掉换行符,所以它会进行多行匹配。
替代方案
修改正则
移除行内容,但保留空行
为避免匹配到空行,请使用 ^(?!\r?\n)(\s+\S+)
在开头放置 (?!\r?\n) 可以跳过以换行符开头的行。然而,全量替换仍会留下一个空白行,导致
-ExcludeProperty
-ExpandProperty
-InputObject
-Property
-Unique
-Wait
这些可以通过:编辑 -> 行操作 -> 删除空行 来移除。
删除整行
使用 ^(?:\r?\n|(\s+\S+))。
这会匹配任意空行或以空白字符开头的行。因此,如果反复应用,它会删除空白行,但不会匹配下一行的内容。
标记并删除
你可以保留相同的正则表达式,但改成以下步骤
- 在搜索工具中切换到“标记”标签(Ctrl+M,或从“查找/替换”标签切换到标记)。
- 选中“书签整行”。
- 输入你想要的正则表达式。
- 点击“全部标记”。
这会标记匹配的行,随后可以通过:顶部菜单 -> 搜索 -> 书签 -> 删除书签的行 来删除。若你想保留匹配正则的行,还有一个选项是“删除未加书签的行”。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。