我使用grep创建了一个测试,但它在sed中不起作用。
grep
sed
grep -P '(?<=foo)bar' file.txt
这通过返回bar正确工作。
bar
sed 's/(?<=foo)bar/test/g' file.txt
我期待footest作为输出,但它没有工作。
footest
oogrdqng1#
GNU sed不支持lookaroundAssert。您可以使用功能更强大的语言,如Perl,或者尝试使用支持Perl风格正则表达式的ssed。
ssed
perl -pe 's/(?<=foo)bar/test/g' file.txt
clj7thdc2#
请注意,大多数情况下,您可以使用捕获组和替换字符串中的反向引用来避免向后查找(或向前查找):
sed 's/\(foo\)bar/\1test/g' file.txt
模拟一个负的向后看是更微妙的,需要几个替换来保护你想要避免的子串。例如(?<!foo)bar:
(?<!foo)bar
sed 's/#/##/g;s/foobar/foob#ar/g;s/bar/test/g;s/foob#ar/foobar/g;s/##/#/g' file.txt
#
##
foobar
foob#ar
ba
b#a
显然,您还可以在捕获组中描述bar之前所有不是foo的内容:
foo
sed -E 's/(^.{0,2}|[^f]..|[^o].?)bar/\1test/g' file.txt
但它会很快变得乏味与更多的字符。
56lgkhnf3#
sed不支持lookarounds,但choose(我是作者)支持。它使用PCRE2语法。举例来说:
$ echo "hello bar foobar" | choose -r --sed '(?<=foo)bar' --replace test hello bar footest
它的速度与sed相当。
3条答案
按热度按时间oogrdqng1#
GNU sed不支持lookaroundAssert。您可以使用功能更强大的语言,如Perl,或者尝试使用支持Perl风格正则表达式的
ssed
。clj7thdc2#
请注意,大多数情况下,您可以使用捕获组和替换字符串中的反向引用来避免向后查找(或向前查找):
模拟一个负的向后看是更微妙的,需要几个替换来保护你想要避免的子串。例如
(?<!foo)bar
:#
=>##
)。foobar
,=>foob#ar
或ba
=>b#a
)。foob#ar
替换为foobar
(或将b#a
替换为ba
)。##
替换为#
。显然,您还可以在捕获组中描述
bar
之前所有不是foo
的内容:但它会很快变得乏味与更多的字符。
56lgkhnf3#
sed不支持lookarounds,但choose(我是作者)支持。它使用PCRE2语法。
举例来说:
它的速度与sed相当。