我有一些像这样的XML数据
<!--Q1: some text--><!--Q1: some text--><!--Q1: some text-->
我想按顺序替换此查询号
<!--Q1: some text--><!--Q2: some text--><!--Q3: some text-->..
我写了这个Perl脚本
#!/usr/bin/perl -w
$b=1;
use strict;
open(FILE, "<text.xml") || die "File not found";
my @lines = <FILE>;
close(FILE);
my @newlines;
while<> {
$_ =~ s/<!--Q[0-9]{1,2}/<!--Q$b/g;
$b++;
push(@newlines,$_);
}
open(FILE, ">text.xml") || die "File not found";
print FILE @newlines;
但它只在每一行中进行一次替换。
我的文字:
<!--Q2: text-->
<!--Q3: text--><!--Q8: text-->
<!--Q10: text-->
输出
<!--Q1: text-->
<!--Q**2**: text--><!--Q**2**: text-->
<!--Q3: text-->
答案 0 :(得分:3)
您的计划存在许多问题
您必须始终use strict
和use warnings
作为您计划的第一行
您应该使用词汇文件句柄(标量变量)而不是全局名称
您应该使用open
的三参数形式,如果$!
失败,则在die
字符串中包含内置变量open
您永远不会使用$a
或$b
作为变量名称。它们根本没有帮助记录程序,它们由perl内部使用,所以你不能依赖它们的内容
您已将整个文件读入@lines
,然后希望在while
循环中有更多内容可供阅读。您已经到达文件末尾,因此永远不会输入循环
在<!--Q
之后测试完全一位或两位数是毫无意义的。如果有三位或更多位数的发生,那么正则表达式仍将匹配,但只会替换前两位数字
没有理由push
将修改后的行添加到数组中,并print
将它们全部放在后面。只需在更改时打印每一个
请改用它。正则表达式中的\K
构造需要Perl 5的10.0版。它自2007年以来一直存在,所以如果你落后于你的更新,那么你应该真正解决这个问题。
use strict;
use warnings;
use 5.010;
open my $in, '<', 'text.xml' or die $!;
open my $out, '>', 'newtext.xml' or die $!;
my $n = 0;
while (<$in>) {
s/<!--Q\K\d+/++$n/ge;
print $out $_;
}
<强>输出强>
<!--Q1: text-->
<!--Q2: text--><!--Q3: text-->
<!--Q4: text-->
<强>更新强>
如果你没有可用的Perl 5版本10(并且你真的应该 - 它是六年旧并且是主要更新)那么你可以像这样编写正则表达式
s/(<!--Q)\d+/$1.++$n/ge;