Perl正则表达式匹配和删除

Azl*_*lam 4 regex perl

我有一个字符串,开始//#...上升到换行符.我已经找到了正则表达式,这就是这个..#([^\n]*).

我的问题是如果以下条件匹配,如何从文件中删除此行

Ari*_*zis 27

你的正则表达式在几个方面被严重挑选:

  1. 你没有专门匹配两个斜杠,而是使用..匹配两个可能是任何东西的字符,大概是因为当你还将它们用作分隔符时你不知道如何匹配斜杠.(实际上,点几乎可以匹配任何东西,正如我们在#3中看到的那样.)

    在斜线划分的正则表达式文字中//,您可以通过使用反斜杠保护它们来匹配斜杠,例如./\/\//.然而,更好的变体是使用较长形式的正则表达式字面值,m//您可以在其中选择分隔符,例如.m!!.因为你使用斜杠以外的东西进行分隔,你可以在不转义它们的情况下编写它们:m!//!.见perldoc perlop.

  2. 它没有锚定到字符串的开头,因此它将匹配任何地方.使用^前面的字符串开头断言.

  3. [^\n]当有一种更简单的方法来编写时,你编写了匹配"除换行之外的任何字符",这只是.通配符.它确切地说 - 匹配除换行符之外的任何字符.

  4. 您正在使用括号对匹配的一部分进行分组,但该组既没有量化(您没有指定它可以匹配任何其他次数而不是一次),您也不想保留它.因此括号是多余的.

总而言之,这就是它m!^//#.*!.但是在正则表达式的末尾放置一个未被捕获的.*(或带有*量词的任何东西)是没有意义的,因为它永远不会改变一个字符串是否匹配:*很高兴根本没有匹配.

所以这让你失望m!^//#!.

至于从文件中删除行,正如其他人解释的那样,逐行读取并打印要保留的所有行到另一个文件.如果您不是在更大的程序中执行此操作,请使用perl的命令行开关轻松完成:

perl -ni.bak -e'print unless m!^//#!' somefile.txt
Run Code Online (Sandbox Code Playgroud)

在这里,-n开关使perl在你提供的代码周围放置一个循环,它将按顺序读取你在命令行上传递的所有文件.该-i开关(即"就地")说来收集你的脚本输出,并用其覆盖每个文件的原始内容.该选项的.bak参数-i告诉perl将原始文件的备份保存在以.bak附加原始文件名命名的文件中.对于所有这些位,请参阅perldoc perlrun.

如果你想在一个更大的程序的上下文中这样做,最安全的方法是打开文件两次,一次用于读取,另一次用IO :: AtomicFile,另一次写入.IO :: AtomicFile只有在成功关闭后才会替换原始文件.


kix*_*ixx 5

要过滤掉文件中与某个正则表达式匹配的所有行:

perl -n -i.orig -e 'print unless /^#/' file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

-i 开关后的“.orig”使用给定的扩展名 (.orig) 创建文件的备份。如果不需要备份,可以跳过它(只需使用 -i)。

-n 开关使 perl 为文件中的每一行执行您的指令 (-e ' ... ')。该行存储在 $_ 中(这也是许多指令的默认参数,在这种情况下:打印和正则表达式匹配)。

最后,-e 开关的参数表示“打印该行,除非它与行首的 # 字符匹配。

附注。还有一个 -p 开关,其行为类似于 -n,除了始终打印行(适合搜索和替换)