如何匹配仅遵循特定模式的第二个模式?
How to match all for a second pattern that follows a particular pattern only?
使用 pcre,我想仅在以 foobar
?
开头的行上将所有 foo
替换为 bar
输入:
foobar foo foo foo foo
foobaz foo foo foo foo foo
输出:
foobar bar bar bar bar
foobaz foo foo foo foo foo
我天真地尝试 \K
喜欢:
s/^foobar\Kfoo/bar/g
不幸的是,它不起作用。例如,使用 Perl 我可以这样做:
s/^foobar(.*)/$&=~s#\bfoo\b#bar#gr/gme
有没有办法做到这一点,例如 https://regex101.com/?
您可以在正则表达式中将 \K
与 \G
运算符结合使用:
(?m)(?:(?!^)\G|^foobar\b)(?:(?!\bfoo\b).)*\K\bfoo\b
其中 (?:(?!\bfoo\b).)*
tempered greedy token 与 .*?
同义。如果 foobar
和 foo
之间没有要排除的子字符串,.*?
的性能会更好,但是,如果您想进一步限制 foobar
和 foo
,您将需要令牌。
如果您对整个单词搜索不感兴趣,单词边界可能会变得多余。
详情:
(?m)
- 开启多行模式
(?:(?!^)\G|^foobar\b)
- 仅匹配上一个成功匹配的结尾((?!^)\G
其中 \G
匹配字符串的开头或上一个成功匹配的结尾,因此 (?!^)
是排除字符串开头的位置所必需的)或一行开头的整个单词 foobar
(^
由于 (?m)
标志与行开始位置匹配)
(?:(?!\bfoo\b).)*
- 匹配除换行符号以外的任何字符,0 次以上,如果字符未开始 foo
序列,即整个单词( 或者 只需将此部分替换为 .*?
,因为在 foobar
和 foo
).[=58= 之间没有要排除的文本]
\K
- 省略目前匹配的文本
\bfoo\b
- 一个完整的单词 foo
是的,使用此 \G (上一个匹配项之后的位置或字符串的开头) 基于模式:
(?:\G(?!\A)|(?m)^foobar\b).*?\K\bfoo\b
使用 pcre,我想仅在以 foobar
?
foo
替换为 bar
输入:
foobar foo foo foo foo
foobaz foo foo foo foo foo
输出:
foobar bar bar bar bar
foobaz foo foo foo foo foo
我天真地尝试 \K
喜欢:
s/^foobar\Kfoo/bar/g
不幸的是,它不起作用。例如,使用 Perl 我可以这样做:
s/^foobar(.*)/$&=~s#\bfoo\b#bar#gr/gme
有没有办法做到这一点,例如 https://regex101.com/?
您可以在正则表达式中将 \K
与 \G
运算符结合使用:
(?m)(?:(?!^)\G|^foobar\b)(?:(?!\bfoo\b).)*\K\bfoo\b
其中 (?:(?!\bfoo\b).)*
tempered greedy token 与 .*?
同义。如果 foobar
和 foo
之间没有要排除的子字符串,.*?
的性能会更好,但是,如果您想进一步限制 foobar
和 foo
,您将需要令牌。
如果您对整个单词搜索不感兴趣,单词边界可能会变得多余。
详情:
(?m)
- 开启多行模式(?:(?!^)\G|^foobar\b)
- 仅匹配上一个成功匹配的结尾((?!^)\G
其中\G
匹配字符串的开头或上一个成功匹配的结尾,因此(?!^)
是排除字符串开头的位置所必需的)或一行开头的整个单词foobar
(^
由于(?m)
标志与行开始位置匹配)(?:(?!\bfoo\b).)*
- 匹配除换行符号以外的任何字符,0 次以上,如果字符未开始foo
序列,即整个单词( 或者 只需将此部分替换为.*?
,因为在foobar
和foo
).[=58= 之间没有要排除的文本]\K
- 省略目前匹配的文本\bfoo\b
- 一个完整的单词foo
是的,使用此 \G (上一个匹配项之后的位置或字符串的开头) 基于模式:
(?:\G(?!\A)|(?m)^foobar\b).*?\K\bfoo\b