perl 正则表达式负向前瞻替换为通配符

问题描述 投票:0回答:1

更新了真实且更复杂的任务:

问题是使用或不使用 _ndm 将某种模式替换为不同的结果。

输入是一个文本文件,其中包含某些行,例如:

/<random path>/PAT1/<txt w/o _ndm>
/<random path>/PAT1/<txt w/ _ndm>

我需要将它们更改为

/<ramdom path>/PAT1/<sub1>
/<random path>/PAT1/<sub2>_ndm

我写了一个perl命令来处理它:

perl -i -pe 's#PAT1/.*_ndm#<sub2>_ndm#; s#PAT1/.*(?!_ndm)#<sub1>#' <input_file>

但是,它并没有按预期工作。全部替换为 _ndm。


原帖:

我需要使用 shell 命令将任何不以 _ndm 结尾的字符串替换为另一个字符串(这是一个示例):

abc
def
def_ndm

ace
ace
def_ndm

我尝试使用 perl 命令

perl -pe 's/.*(?!_ndm)/ace/'

但是我发现通配符不能像我预期的那样与负向前瞻一起使用。只有当我在否定模式中包含通配符时,它才能正确跳过 def_ndm ;但因为负向先行是零长度的,所以它不能再代替普通字符串。

有什么想法吗?

perl wildcard regex-lookarounds
1个回答
0
投票

正如您所发现的,

"PAT1/txt_ndm" =~ m#PAT1/.*(?!_ndm)#
匹配。具体来说,它匹配
PAT1/txt_ndm
。请注意,
PAT1/txt_ndm
后面没有
_ndm

要仅匹配

_ndm
(
PAT1/txt
) 之前的文本,您可以使用以下命令:

PAT1/(?:(?!_ndm).)*
© www.soinside.com 2019 - 2024. All rights reserved.