正则表达式空格到锚点(\ s * $)消耗换行符

时间:2015-09-18 01:15:53

标签: regex perl

默认情况下,行尾锚点应该占据最后一个字符和换行符之间的虚构位置。 为什么' \ s * $'在以下示例中使用换行符?

perl -pe 's/(\.\d{4})\d+\s*$/\1/'

上述替换的目的是将digit.5 +数字截断为digit.4digits
例如:123.54321 -> 123.5432

我不想浪费时间转换" .5 +数字非数字" (例如:5.12345 blah)因为它无论如何都会失败预加载验证。

/home/mlibby> echo -e '38492.38945\n5.12345 blah\n624.54321  \n9.325437' | perl -pe 's/(\.\d{4})\d+$/\1/'
38492.3894
5.12345 blah
624.54321
9.3254

然而,我想要转换" .5 +数字空白" (例如:624.54321)因为尾随空格有效,但应该修剪。 因此,在我消耗了5对多的数字之后,我说\s*$消耗零或更多的空格直到主题结束锚。

/home/mlibby> echo -e '38492.38945\n5.12345 blah\n624.54321  \n9.325437' | perl -pe 's/(\.\d{4})\d+\s*$/\1/'
38492.38945.12345 blah
624.54329.3254/home/mlibby>

那么,为什么上面的搜索模式消耗换行符,导致替换删除LF并最终截断行?

当然,我可以将我的替换更改为\1\n,但这篇文章的重点是了解这里发生了什么。默认情况下,$应该固定在换行符的西边。这里发生了什么?

仅供参考:RHEL 5.8上的Perl版本5.8.8

2 个答案:

答案 0 :(得分:3)

$匹配两个地方的 :在字符串的末尾,或紧接在字符串末尾的换行符之前。

换行符是一种空格,因此\s匹配它。因此,\s*消耗任何尾随空格包括换行符,并且由于$匹配字符串末尾即使没有换行符,也不会强制回溯。

您可以使用非贪婪的匹配\s*?来匹配尽可能少的空格,从而保证它不会占用$准备忽略的换行符。

或者你可以匹配任何不是换行符的空格,即[^\S\n](如果这看起来很奇怪,请考虑De Morgan定律 - NOT((不是空格)或换行符)==空格AND(不是换行符) )

答案 1 :(得分:0)

\s匹配换行符,$匹配输入结尾(在最后一个字符之后)

更改正则表达式以仅匹配非换行符空格(例如空格和制表符):

perl -pe 's/(\.\d{4})\d+[ \t]*$/\1/'