正则表达式:仅在子字符串中替换字符串

我有一种特殊的文件格式,需要替换几十个字符串并重新格式化其结构。作为最简单的解决方案,我准备了我的patterns文件,其中存储了所有正则表达式定义/替换(〜100个替换)。我正在使用perl查找和替换模式(perl -p patterns source.file)。到目前为止一切都很好。

但是,有一种情况我无法使用正则表达式解决。我需要在整个行的一部分中替换字符串,即仅在子字符串中替换字符串。

示例:为简单起见,我只需要在中间字符串(用;分隔)中将所有“ A”替换为“ X”。

输入行:

ABCD ABCD; ABCD ABCD; ABCD ABCD

预期输出:

ABCD ABCD; XBCD XBCD; ABCD ABCD
           ^    ^
           the only replaced characters

这将正确替换所有字符:

s/A/X/g;

但是我只需要在中间字段中替换逗号。我尝试过:

s/(.*?;.*?)A/\1X/g;
s/(.*?;.*)A(.*?;)/\1X\2/g;  # alternative to find the last A

但是这将替换第一个A。我可以有多个类似的模式来重复搜索和替换过程,但这听起来不是一个好的解决方案,因为我不知道子字符串中将有多少个A。

我尝试过向后看,但未成功。请注意,我只需要可以在我的模式文件中使用的正则表达式定义(即没有perl代码)。另外,我可以使用sedawk来处理这种情况,但我对此不太熟悉。

谢谢,社区!

Regex101:https://regex101.com/r/Ic4ciA/1

bugandang 回答:正则表达式:仅在子字符串中替换字符串

每一个perl班轮:

echo 'ABCD ABCD; ABCD ABCD; ABCD ABCD' | perl -pe 's/(?:.+?;|\G).*?\KA(?=.*?;)/X/g'
ABCD ABCD; XBCD XBCD; ABCD ABCD

说明:

(?:             # non capture group
    .+?         # 1 or more any character but newline,not greedy
    ;           # semicolon
  |             # OR
    \G          # restart from last match position
)               # end group
.*?             # 0 or more any character but newline,not greedy
\K              # forget all we have seen until  this position
A               # letter A
(?=             # positive lookahead,make sure we have after:
    .*?         # 0 or more any character but newline,not greedy
    ;           # a semicolon
)               # end lookahead

Demo

,

我不知道一种单独使用正则表达式工具的简单方法。但是,如果您愿意采用更迭代的方法,则可以使用任何脚本语言轻松地对其进行处理。这是完成工作的Python脚本:

inp = "ABCD ABCD; ABCD ABCD; ABCD ABCD"
parts = inp.split(';')

index = 1
while index < len(parts)-1:
    parts[index] = parts[index].replace('A','X')
    index += 1

output = ';'.join(parts)
print(output)

此打印:

ABCD ABCD; XBCD XBCD; ABCD ABCD

方法是在分号上分割输入字符串,生成一个术语列表。然后,从第二项到倒数第二项进行迭代,将字母A替换为X。最后,结合在一起以产生所需的输出。

本文链接:https://www.f2er.com/3167785.html

大家都在问