用外部文件中的行替换正则表达式匹配

时间:2012-10-18 16:15:28

标签: regex perl

使用Perl,我正在解析一个文本文件并希望找到一个关键字和文件名,然后我需要打开该文件(它与正在解析的文件位于同一目录中),从中获取文本,并在比赛结束后插入。

file1 =正在解析的文件

file2 =要包含的文件

开头两个文件的示例:

file1
code code code
%include file2;
code code code

file2
(* a bunch of header information *)
function ( arg : type);

我希望file1看起来如下:

file1
code code code
(*%include file2;*)
(* a bunch of header information *)
function ( arg : type);
code code code

我需要帮助开发perl才能执行此替换。

我编写了以下文件,用于解析文件并将其作为字符串读取。我想保留这种方法,因为我已经使用它实现了几个替换,但其余的是开放季节。我也喜欢理解这些内容,所以如果您不介意对提交的解决方案进行简要说明,我们将不胜感激。

#keep this part
open FILEHANDLE, "<", $file or die $!;
$string = do { local $/; <FILEHANDLE> };

#several other replace operations here already written
$string ~= s/match/replace;

#can rewrite this to be anything that works well
#match the include tag
if ($string =~ m/^%include\s+'(\w+).(PRO)'/gi)
{
  #build the replace string
  my $includefile = $1.'.'.$2;
  my $replacestring = "(* $& *) \n";
  open my INCLUDEHANDLE, "<", $includefile or die $!;
  $replacestring += do { local $/; <INLCUDEHANDLE> }

  # I am lost at this point
}

#this is dirty but it works
#close file for read
close FILEHANDLE;
#open file for write
open FILEHANDLE, ">", $file or die $!;
print FILEHANDLE $string;
#close file for write
close FILEHANDLE;

Internet帮助清理我的文件读/写操作以及从文件2的内容中剥离(*标题信息*),然后将其写入file1,如下所示:

file1
code code code
(*%include file2*)
function ( arg : type);
code code code

2 个答案:

答案 0 :(得分:0)

除非你有一些复杂的比赛要做,否则你可以使用单线:

perl -pi.bak -lwe'$x=qx(cat rep.txt); s/(%include file2;)/(*$1*)$x/g' file1.txt

这会将整个文件“rep.txt”读入$x,然后在匹配后插入。

依赖qx()这是一个系统调用并且不可移植是不理想的。写一个开环会更好。

答案 1 :(得分:0)

如果您的文件足够小以至于笨拙,那么您的任务只是一个花哨的字符串替换:

use strict;
use warnings;

# function to replace the match with a string (slurped from
# a file mentioned in group)
sub magic_replace {
    my ($m, $g) = @_;
    sprintf "(%s)\nPlease slurp this from '%s'", $m, $g;
}

my $s =<<'EOF'
I should have
slurped
%include file2.ext2;
this from
%include file3.ext3;
file1.ext1
EOF
;

print "---------\n", $s, "---------\n";

$s =~ s/(%include\s([^;]+);)/
   magic_replace($1, $2)
   /egx;

print "---------\n", $s, "---------\n";

输出:

perl 12959116.pl
---------
I should have
slurped
%include file2.ext2;
this from
%include file3.ext3;
file1.ext1
---------
---------
I should have
slurped
(%include file2.ext2;)
Please slurp this from 'file2.ext2'
this from
(%include file3.ext3;)
Please slurp this from 'file3.ext3'
file1.ext1
---------

使用'回调'功能进行替换操作可让您专注于(啜饮和)构建替换,并完成所有循环。

(我们的正则表达式都可能需要一些修补 - 你的点,我对虚假空白的疏忽。)

更新(评论中的问题)

如果您在模式中添加“^”,则需要应用m modifier