我在文本文件中有一行说:
$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
}
}
答案 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;
\K
是lookbehind的一种形式,断言,其前面的模式确实存在。它还会丢弃所有先前的匹配,允许\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
}
这可能比内联替换更容易理解