我有一个文件需要转换为自定义代码页。该文件具有以下内容:

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),您的测试字符串不包括这种情况。我在上面加了

10-07 15:05