Perl Regex:文本文件

时间:2017-04-18 20:27:19

标签: regex perl

我在文本文件中有一行说:

$cacheVersion_conference = '2';

我想增加数字2。

我认为我与"$cacheVersion_conference = "匹配:

[\n\r].*$cacheVersion_conference = \\s*([^\n\r]*)

这样,我可以匹配并替换所有内容,直到下一行增加数字。

更新 - 回写到源文件的答案。需要安装Path :: Tiny

#!/usr/bin/perl -w
use strict;
use warnings;

use Path::Tiny qw(path);

my $filename = 'my/source/file.php';

my $file = path($filename);

open my $fh, '<', $filename or die "File open err: $!";

while (<$fh>) {  # read the file line by line
    if (/\$cacheVersion_conference = '(\d+)';/) { # match the line & capture the digit(s)
       my $new_ver = $1 + 1; # increment the digit
       my $line = <$fh>;
       chomp $line;

       my $replacement = "\$cacheVersion_conference = '$new_ver';\n"; 

       my $data = $file->slurp_utf8;
       $data =~ s/$line/$replacement/g;
       $file->spew_utf8( $data );

       print $replacement; # print newly constructed line 
    }
}

3 个答案:

答案 0 :(得分:3)

听起来您已将整个文件读入标量变量。这种方法非常受欢迎,并且使得这样的任务比使用更多内存所需的内容更加尴尬

除非有充分的理由将整个文件同时存储在内存中,否则您应该一次读取一行。如果这是 all 你必须对文件做什么,那么它看起来像这样

open my $fh, '<', 'myfile.txt' or die $!;

while ( <$fh> ) {
    s/(\d+)/$1+1/e if /\$cacheVersion_conference/;
    print;
}

答案 1 :(得分:2)

假设您逐行阅读$line变量

$line =~ s/^\$cacheVersion_conference\s*=\s*\K'(\d+)'/ q(') . (1+$1) . q(') /e;

\Klookbehind的一种形式,断言,其前面的模式确实存在。它还会丢弃所有先前的匹配,允许\K处理可变长度模式。

/e使得替换方被评估为代码,并且我们递增数字并重新组合引用的数字'N'。它必须是合法代码,因此需要引用文字q('),我们需要将字符串与.连接,并用括号中的表达式(1+$1)连接。

或者,您可以捕获所有内容,然后重新组合整个内容

$line =~ s/^(\$cacheVersion_conference\s*=\s*)'(\d+)'/$1.q(').(1+$2).q(')/e;

答案 2 :(得分:2)

你想要做的是这样的事情:

open (my $IN, '<', 'yourFile.txt') or die ('IN File err: '. $!);
open (my $OUT, '>', 'newFile.txt') or die ('OUT file err: '. $!);

while (<$IN>) {  # read the file line by line
    if (/\$cacheVersion_conference = '(\d+)'/) { # match the line & capture the digit(s)
       my $new_ver = $1 + 1; # increment the digit
       print $OUT "\$cacheVersion_conference = '$new_ver';\n"; # print newly constructed line 
    }
    else {print $OUT} # print out the unmatched, unchanged lines
}

这可能比内联替换更容易理解