作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
为什么第2行和第3行的开头有一个美元符号?
➜ echo -e "hello\nworld" | perl -pe 's/$/\$/g'
hello$
$world$
$%
上面,我试图在每行的末尾添加一个美元符号,但不知何故它也在开头附加了一个美元符号。它在启用全局标志时执行此操作。但是当我删除全局标志时,它工作正常:
➜ echo -e "hello\nworld" | perl -pe 's/$/\$/'
hello$
world$
谁能解释一下发生了什么?也许它与'\r\n'字符有关?
编辑:添加回顾案例
不仅在这种情况下会发生故障,在其他情况下也会发生故障。请考虑以下事项:
➜ echo -e "A\nB\nC\nD" | perl -pe 's/(?<!A)$/\$/'
A
$B$
C$
D$
上面,我想用 $ 标记不以“A”结尾的行。第 2 行中的额外美元符号不应存在。我什至没有使用全局标志。
解决方案:好的,现在明白了。第二个的解决方法是这样的(解释引用Wiktor Stribiżew's answer)
➜ echo -e "A\nB\nC\nD" | perl -pe 's/(?<!A|\n)$/\$/'
A
B$
C$
D$
但是注意,如果你尝试使用多个字符,它会抛出可变长度 lookbehind 未在正则表达式中实现
。例如:
➜ echo -e "AA\nBB\nCC\nDD" | perl -pe 's/(?<!AA|\n)$/\$/'
Variable length lookbehind not implemented in regex m/(?<!AA|\n)$/ at -e line 1.
要解决此问题,请在换行符前添加适当数量的 .
。
➜ echo -e "AA\nBB\nCC\nDD" | perl -pe 's/(?<!AA|.\n)$/\$/'
AA
BB$
CC$
DD$
最佳答案
重点是 $
是一个零宽度断言,它可以在最后一个换行符之前匹配。 Perl 读取尾随 \n
的行,因此 $
匹配两次:在此之前和之后。
您的字符串基本上以两行形式发送给 Perl:
hello\n
world\n
$
可以匹配最后一个换行符之前和字符串的末尾。因此,两行中都有两个匹配项(在此上下文中为“字符串”)。
如果你想匹配字符串的最后,使用\z
:
perl -pe 's/\z/\$/g'
因为 \z
只匹配字符串的very 结尾,但不太可能有人想使用它,因为它会有效地插入一个 $
在第二行和后续行的开始,并将其添加为最后一行。
要仅在最后一个 \n
之前插入 $
并停止,请使用 perl -pe 's/$/\$/'
, 没有 g
修饰符。
关于用 perl 替换正则表达式 EOL 会产生意想不到的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49045418/
我是一名优秀的程序员,十分优秀!