sed:具有反向前瞻匹配的嵌套组

Posted

技术标签:

【中文标题】sed:具有反向前瞻匹配的嵌套组【英文标题】:sed: Nested group with inverse lookahead matching 【发布时间】:2022-01-07 02:46:40 【问题描述】:

我正在尝试用图像bar 替换除 URL 之外的所有 URL 的图像标记。但是,它说正则表达式无效。 只检查 regex101.com 上的正则表达式 (image:(?!.*bar).*:).* 看起来不错。将 sed 表达式的第二部分替换为组 (image:(?!.*bar).*:) 时出现错误。

$ echo '
image: mydomain/subdomain/foo:old_tag
image: mydomain/subdomain/bar:dont_update_me_tag
image: mydomain/subdomain/baz:old_tag
' | sed --regexp-extended "s|(image:(?!.*bar).*:).*|\1new_tag|g"
sed: -e expression #1, char 36: Invalid preceding regular expression

预期的最终结果是:

image: mydomain/subdomain/foo:new_tag
image: mydomain/subdomain/bar:dont_update_me_tag
image: mydomain/subdomain/baz:new_tag

正则表达式(image:(?!.*bar).*:).*的解释 搜索所有包含image:.*:.* 的行,但包含image:.*bar 的行除外

【问题讨论】:

(?!...) 是 Perl 扩展,--regexp-extended 不会将sed 转换成 Perl。 【参考方案1】:

POSIX ERE 仍然不支持环视。幸运的是,您可以匹配具有特定模式的行并跳过它,然后匹配您需要的任何内容:

sed -E "/image:.*bar/!s/(image:.*:).*/\1new_tag/"

见online demo:

echo '
image: mydomain/subdomain/foo:old_tag
image: mydomain/subdomain/bar:dont_update_me_tag
image: mydomain/subdomain/baz:old_tag
' | sed -E "/image:.*bar/!s/(image:.*:).*/\1new_tag/"

输出:

image: mydomain/subdomain/foo:new_tag
image: mydomain/subdomain/bar:dont_update_me_tag
image: mydomain/subdomain/baz:new_tag

【讨论】:

也许您应该在使用 .* 正则表达式时删除 g 标志,并且替换命令的不匹配地址在整个行中都是全局的。 @potong 这是 OP 命令的余数。我认为即使有g 也没有什么坏处,但留在那里肯定是没有意义的。【参考方案2】:

这可能对你有用(GNU sed):

sed -E 's/^/\n/
       :a;ta
       s/\n(image: \S*bar\S*)/\1\n/;ta
       s/\n(image: \S*:)\S*/\1new_tag\n/;ta
       s/\n(.)/\1\n/;ta
       s/\n$//' file

一次处理一行。

在行首引入换行符。

如果换行符后面的字符串是带有bar 的图像,则跳过它,移动换行符并重复。

如果换行符后面的字符串是没有bar的图像,则用新标签替换它,移动换行符并重复。

否则,将换行符移到下一个字符并重复。

当换行符不能再移动时,删除它,打印当前行并重复。

注意不能使用替换命令的g 标志,因为必须单独比较图像的每个实例。如果每行只有一个图像而没有其他图像,则使用@Wiktor Stribiżew 解决方案。

【讨论】:

感谢您分享详细的解释和答案。如果 \n 仅被 GNU sed 识别,您能否告诉我?或者还有其他可以识别它的 sed 版本? @RavinderSingh13 我只使用过 GNU sed,而且我知道其他 sed 确实存在问题,这就是为什么我总是(可能!)按上述方式限定我的解决方案。另一个question 可能会更清楚地说明这个问题。

以上是关于sed:具有反向前瞻匹配的嵌套组的主要内容,如果未能解决你的问题,请参考以下文章

具有估计高度的 UICollectionViewCompositionalLayout 嵌套组

python搜索替换n个非嵌套组的匹配

如何在具有角度嵌套数据组的材料表中显示拆分标题

具有多个嵌套组的 Select2

Linq:获取具有多个嵌套组的内部对象的小计

具有多个嵌套模型的 Rails 表单会导致无线电组出现问题