我正在学习 perl 正则表达式,并尝试组合捕获组并指定字符串的第 n 次出现。
假设我有以下内容:
title="alpha" lorem ipsum lorem ipsum name="beta" Morbi posuere metus purus name=delta Curabitur ullamcorper finibus consectetur name=sigma
我想将 title
属性更改为第 n 个 name=
之后的字符串,例如sigma
,同时保留所有内容。此外,name=
可能有双引号,例如 name="beta"
或 name=sigma
。
name=
的第一次出现:
title="beta" lorem ipsum lorem ipsum Morbi posuere metus purus name=delta Curabitur ullamcorper finibus consectetur name=sigma
name=
第二次出现:
title="sigma" lorem ipsum lorem ipsum name="beta" Morbi posuere metus purus name=delta Curabitur ullamcorper finibus consectetur
我用:
find . -type f -exec perl -pi -w -e 's/(title=)"?[^"\s]*"?(.*) name="?([^"\/]+)"?/$1"$3"$2/' \{\} \;
这适用于 name=
的第一次出现。
我不知道如何修改它来指定 name=
的第 n 次出现。
我知道指定第 n 次出现的基础知识(例如 将第二个 abc
替换为 xyz
),...
s/abc/ ++$count == 2 ? "xyz" : "abc" /eg
...但无法将其集成到我上面的代码中。如何指定第 n 个 name=
并将其以下捕获组移动到 title
属性的位置?
最佳答案
您可以使用模式在 {n}
部分中设置手动量词,并可选择重复 key=value 对以找到您感兴趣的对象。
(title=)"?[^\s="]+"?(\h+(?:.*?[^\s=]+=[^\s=]+){0}.*?)[^\s=]+="?([^\s="]+)"?\h*
^^^
模式匹配:
(title=)"?[^\s="]+"?
捕获 group 1,匹配title=
并匹配替换后您不想保留的值(
捕获 第 2 组\h+
匹配 1+ 个空格(?:.*?[^\s=]+=[^\s=]+){0}
n 次重复前面的 key=value对
.*?
尽可能少匹配任何字符)
关闭第二组[^\s=]+=
匹配除空白字符或=
之外的任何字符 1 次以上,然后匹配=
关键部分"?([^\s="]+)"?
捕获 1+ 字符而不是空白字符=
或"
在第 3 组可选双引号之间\h*
匹配可选的尾随空格
查看 0 repetitions 的正则表达式演示, 1 repetition和 2 repetitions .
在 {0}
{1}
和 {2}
find . -type f -exec perl -pi -w -e 's/(title=)"?[^\s="]+"?(\h+(?:.*?[^\s=]+=[^\s=]+){0}.*?)[^\s=]+="?([^\s="]+)"?\h*/$1"$3"$2/' \{\} \;
将文件更改为:
title="beta" lorem ipsum lorem ipsum Morbi posuere metus purus name=delta Curabitur ullamcorper finibus consectetur name=sigma
title="delta" lorem ipsum lorem ipsum name="beta" Morbi posuere metus purus Curabitur ullamcorper finibus consectetur name=sigma
title="sigma" lorem ipsum lorem ipsum name="beta" Morbi posuere metus purus name=delta Curabitur ullamcorper finibus consectetur
关于regex - Perl 正则表达式捕获组和第 n 次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73239362/