Regex 用perl替换正则表达式EOL会产生意外的结果
为什么在第2行和第3行的开头有一个美元符号?Regex 用perl替换正则表达式EOL会产生意外的结果,regex,linux,perl,Regex,Linux,Perl,为什么在第2行和第3行的开头有一个美元符号? ➜ echo-e“hello\nworld”| perl-pe's/$/\$/g' 你好$ $world$ $% 在上面,我试图在每一行的末尾添加一个美元符号,但不知怎么的,它在开头也添加了一个美元符号。当启用全局标志时,它会执行此操作。但当我移除全球标志时,它工作正常: ➜ echo-e“hello\nworld”| perl-pe的/$/\$/' 你好$ 世界$ 有人能解释发生了什么事吗?可能与“\r\n”字符有关 编辑:添加查找案例 这不仅
➜ echo-e“hello\nworld”| perl-pe's/$/\$/g'
你好$
$world$
$%
在上面,我试图在每一行的末尾添加一个美元符号,但不知怎么的,它在开头也添加了一个美元符号。当启用全局标志时,它会执行此操作。但当我移除全球标志时,它工作正常:
➜ echo-e“hello\nworld”| perl-pe的/$/\$/'
你好$
世界$
有人能解释发生了什么事吗?可能与“\r\n”字符有关
编辑:添加查找案例
这不仅仅是在这种情况下,但其他情况下,以及打破。考虑以下事项:
➜ echo-e“A\nB\nC\nD”| perl-pe的/(?
解决方案:好的,现在知道了。第二个的解决方案是这样的(有关说明,请参阅)
➜ echo-e“A\nB\nC\nD”| perl-pe的/(?要点是,$
是一个零宽度断言,它可以在最后一个换行符之前匹配。perl读取一个尾随\n
的行,因此$
匹配两次:前后
您的字符串基本上以两行形式进入Perl:
hello\n
world\n
而$
可以在最后一行换行之前和字符串的最后一行匹配。因此,这两行中都有两个匹配项(“上下文中的字符串”)
如果要匹配字符串的末尾,请使用\z
:
perl -pe 's/\z/\$/g'
因为\z
只匹配字符串的最末端,但不太可能有人想使用它,因为它会在第二行和后续行的开头插入一个$
,并将其添加为最后一行
要仅在最后一个\n
之前插入$
并停止,请使用perl-pe的/$/\$/'
,不带g
修饰符。如果确实要将其与全局替换一起使用,可以使用以下命令:
echo -e "hello\nworld" | perl -pe 's/^(.*)$/\1\$/g'
hello$
world$
或者如果没有反向引用,您可以使用:
echo -e "hello\nworld" | perl -pe 's/\n$/\$\n/g'
hello$
world$
如果您从windows操作文件或仅使用dos2unix
删除windows EOL字符\r
,\n
可能需要将\n
替换为\r\n我已经尝试了您的命令,但它仍然给我:echo-e“hello\nworld”| perl-pe's/\z/\$/g'hello\n$world\n$
是的,这是预期的,因为它与\n
之后的字符串结尾匹配。我更新了答案。好的,现在我走对了。感谢您消除了混淆。是的,还有其他方法可以做到这一点,但是我的问题是为什么会发生这种情况?因为这不仅仅是在本例中产生问题,在其他情况下也会产生问题。我将在我的帖子中添加其他情况。此外,如果您这样做,您的第二个解决方案将被破坏:echo-ne“hello\nworld”,因为可变长度的lookbehind其他解决方法使用多个反向lookbehinds/(?,或使用负前瞻s/(?@NahuelFouilleul,为什么这样做?多个lookbehind是否自然被OR?每个lookbehind添加了一个新的约束,因此更严格,如和条件:当光标位置匹配$
时,第一个lookbehind告诉引擎检查最后两个字符是否AA
,第二个检查最后一个字符是否为空\n
,关于另一种解决方法第二个检查是一种前瞻性检查,检查它没有自动定位到输入的最末端,因为$
与预期不完全匹配,它可以更改为(?=\n)
:echo-e“AA\nBB\nCC\nDD”| perl-pe的/(?)?