我终于想出了如何将文本附加到文件中每行的末尾:
perl -pe 's/$/addthis/' myfile.txt
然而,由于我正在尝试使用Perl进行常规正则表达式使用,我无法弄清楚为什么以下perl命令将文本'addthis'添加到结尾并开始每一行:
perl -pe 's/$/addthis/g' myfile.txt
我认为'$'匹配线的末尾,无论使用什么修饰符进行正则表达式匹配,但我猜这是错误的?
答案 0 :(得分:10)
摘要:对于您正在做的事情,请删除/g
,使其仅在换行符之前与匹配。 /g
告诉它在字符串末尾的换行符和之前(换行符之后)匹配。
如果没有/m
修饰符,$
将在换行符之前(如果它出现在字符串的末尾)或字符串的末尾匹配。例如,对于"foo"
和"foo\n"
,$
将在foo
之后匹配。但是,对于"foo\nbar"
,它会在bar
之后匹配,因为嵌入换行符不在字符串的末尾。
使用/g
修饰符,您将获得$
匹配的所有位置 - 所以
s/$/X/g;
将采用"foo\n"
之类的行并将其转换为"fooX\nX"
。
<强>侧栏:强>
/m
修饰符将允许$
匹配字符串结尾前出现的换行符,以便
s/$/X/mg;
会将"foo\nbar\n"
转换为"fooX\nbarX\nX"
。
答案 1 :(得分:5)
正如Jim Davis所指出的那样,$
匹配字符串的结尾或\n
字符(/m
选项之前)。 (请参阅Regular Expressions Perldoc页面的perlre部分。使用g
修饰符可以继续匹配。
多行Perl正则表达式(即Perl正则表达式中包含新行符号,即使它只出现在行尾的一次)会导致大多数Perl程序员遇到问题处理的各种复杂情况。
如果您一次只读取一行文件,请在使用该行 ANYTHING 之前使用chomp
。在使用g
限定符时,这可以解决您的问题。
如果您正在阅读来自Windows的Linux / Mac上的文件,则可能会出现更多问题。在这种情况下,您将同时拥有\r
和\n
字符。正如我最近在尝试调试程序时发现的那样,\r
并未删除chomp
字符。我现在确保我总是打开我的文本文件进行阅读
像这样:
open my $file_handle, "<:crlf", $file...
如果这实际上是Linux / Mac系统上的Windows文件,则会自动将\r\n
个字符替换为\n
。如果这是一个普通的Linux / Mac文本文件,它将什么都不做。其他明显的解决方案是不使用Windows( rim shot! )。
当然,在你的情况下,首先使用chomp会做到以下几点:
$cat file
line one
line two
line three
line four
$ perl -pe 'chomp;s/$/addthis::/g`
line oneaddthis::line twoaddthis::line threeaddthis::line fouraddthis::
chomp删除了\n
,所以现在,当打印出来的时候,你看不到它。嗯...
$ perl -pe 'chomp;s/$/addthis/g;print "\n";
line oneaddthis
line twoaddthis
line threeaddthis
line fouraddthis
有效!并且,你的一个班轮只是略微难以理解。
另一件事是在他的书Perl Best Practices的第12章中采用Damian Conway建议的更多现代方法:
使用
\A
和\z
作为字符串边界锚点。即使你没有采用以前总是使用/ m的做法,使用^和$的默认含义也是个坏主意。当然,你知道在Perl正则表达式 1 中^和$实际意味着什么。但阅读或维护代码的人会知道吗?或者他们更有可能以前面描述的方式误解这些元字符? Perl提供的标记始终 - 并且明确地 - 表示“字符串的开头”和“字符串的结尾”:\ A和\ z(大写字母A,但是小写字母z)。它们的意思是“字符串的开始/结束”,无论/ m是否有效。它们的意思是“字符串的开始/结束”,无论读者如何思考^和$ mean。
如果您遵循Conaway的建议,并且这样做了:
perl -pe 's/\z/addthis/mg' myfile.txt
您会看到您的短语addthis
仅添加到每行的末尾:
$cat file
line one
line two
line three
line four
$ perl -pe `s/\z/addthis/mg` myfile.txt
line one
addthisline two
addthisline three
addthisline four
addthis
看看它有多好。 addthis
被添加到每行的最后! ...在该行的\n
字符之后。
足够有趣并重返工作岗位。 (等等,这是总统日。这是一个带薪假期。今天没有工作,当然除了我承诺在星期二早上做的所有事情。)
希望这有助于您了解正则表达式有多么有趣,以及为什么这么多人决定学习Python。
1。了解Perl中^
和$
的真正含义?呃,当然是 我 。我已经在Perl编程了几十年。是的,我知道这些东西。 (自我注意:$
显然并不代表我一直认为的意思。)
答案 2 :(得分:0)
解决方法:
perl -pe 's/\n/addthis\n/'
不需要g
修饰符:正则表达式逐行处理。