我有一个文件需要从自定义代码页中转换出来。该文件包含如下内容:
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
。我在上面添加了
关于regex - 用正则表达式替换字符时忽略 latex 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55555708/