我有一个文件需要转换为自定义代码页。该文件具有以下内容:
foo bar baz \bazfoo \barfoo foo bar \foobar
我想用bar代替foo,除非foo作为LaTeX宏的一部分出现,例如\ bazfoo,\ barfoo和\ foobar
换句话说,
s/foo/bar/
,但是\ bazfoo必须保留\ bazfoo。有没有办法使用lookead运算符来做到这一点? 最佳答案
可以使用否定的字符类要求具有模式的单词不以\
开头
s{(?: ^|\s ) (?: [^\\\s]\S* )? \K foo}{XXX}gx
foo
也可以出现在字符串或单词的开头,因此^|\s
和[^\\\s]\S*
的交替是可选的。 \
需要在字符类中转义,否则它本身会转义]
。\K
会删除所有匹配点,因此我们不必捕获它们并将它们放回去。负向后视不允许使用变长模式,这是一个问题。
测试,除了测试字符串
perl -wE'$_=q(foo bar somefoo \bazfoo \barfoo foo bar \foobar); say;
s{(?: ^|\s ) (?: [^\\\s]\S* )? \K foo}{XXX}gx; say'
版画
foo bar somefoo \bazfoo \barfoo foo bar \foobar
XXX bar someXXX \bazfoo \barfoo XXX bar \foobar
请注意,当
foo
在单词中但仍需要替换时(例如somefoo
),您的测试字符串不包括这种情况。我在上面加了