Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 用perl替换正则表达式EOL会产生意外的结果_Regex_Linux_Perl - Fatal编程技术网

Regex 用perl替换正则表达式EOL会产生意外的结果

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”字符有关 编辑:添加查找案例 这不仅

为什么在第2行和第3行的开头有一个美元符号?

➜ 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其他解决方法使用多个反向lookbehind
s/(?,或使用负前瞻
s/(?@NahuelFouilleul,为什么这样做?多个lookbehind是否自然被OR?每个lookbehind添加了一个新的约束,因此更严格,如
条件:当光标位置匹配
$
时,第一个lookbehind告诉引擎检查最后两个字符是否
AA
,第二个检查最后一个字符是否为空
\n
,关于另一种解决方法第二个检查是一种前瞻性检查,检查它没有自动定位到输入的最末端,因为
$
与预期不完全匹配,它可以更改为
(?=\n)
echo-e“AA\nBB\nCC\nDD”| perl-pe的/(?)?