gpt4 book ai didi

用 perl 替换正则表达式 EOL 会产生意想不到的结果

转载 作者:太空狗 更新时间:2023-10-29 11:07:01 26 4
gpt4 key购买 nike

为什么第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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com