我正在尝试构造一个正则表达式来搜索和替换文件。以下是脚本。
#!use/bin/perl
use strict;
use warnings;
my $line = $ARGV[0];
my $find = "[^a-zA-Z0-9]+seqfile[^a-zA-Z0-9]+=[^a-zA-Z0-9]+[a-z]+..";
my $replace = "done"; open (FILE, ">>/home/user/Desktop/test") || die "cant open file \n";
my @body = <FILE>;
foreach $line (@body) {
if (my $line =~ s/$find/$replace/g){
print FILE $line;
}
else {
print "did not replace \n\n";
}
}
close(FILE);
print "reached here\n";
exit;
我正在运行的测试我的程序的示例测试文件由几行文本组成。我要替换的字符串出现在第一行“tobereplaced = file.aa”。我不得不将carot(^)用于字母/数字以外的字符,因为我的系统中不接受空格“\ s”的正则表达式。我知道程序已执行,因为它打印'到达此处'。谁能建议
由于
答案 0 :(得分:3)
\s
未被接受,因为您使用的是双引号字符串。双引号字符串试图理解\s
并且不知道如何处理它,你可以说下面的任何一些东西让它起作用:
"\\s+seqfile\\s+=\\s+[a-z]+.."
'\s+seqfile\s+=\s+[a-z]+..'
qr/\s+seqfile\s+=\s+[a-z]+../
最后一个是首选形式,因为它创建的编译正则表达式比普通字符串快。如果您在不期望正则表达式的上下文中使用它,则编译的正则表达式将进行字符串化,因此您可以说
print "$find\n";
然后返回(?-xism:\s+seqfile\s+=\s+[a-z]+..)
。
此外,如果要取消字符类,则必须将插入符号放在字符类中:[^a-zA-Z0-9]
表示不是字母数字(至少为ASCII),但^[a-zA-Z0-9]
表示匹配字母数字字符串的开头(如果设置了/m
选项,则为行的开头)。
此外,在>>
模式下打开文件时,您无法从中读取。我已将您的代码更改为从STDIN(或命令行上的文件)读取并写入STDOUT。这是一种称为过滤的标准Perl技术。它允许您构建程序的管道。您可以像这样运行脚本
./script.pl inputfile > outputfile
或者
cat inputfile | ./script.pl > outputfile
这是脚本
#!use/bin/perl
use strict;
use warnings;
my $find = qr{ \s+ seqfile \s+ = \s+ [a-z]+ .. }x;
my $replace = "done";
while (<>) {
s/$find/$replace/g;
print;
}
它也可以归结为单线:
perl -pe 's/\s+seqfile\s+=\s+[a-z]+../done/g' inputfile
学习正则表达式的好资料来源是:
答案 1 :(得分:0)
您已在附加模式下打开文件,然后尝试同时读取和写入该文件。既可以读取也可以写入文件,但需要使用其他模式。但除非您想要替换完全相同数量的字符,否则您将不得不从一个文件中读取并将所有内容(包括已更改和未更改的部分)写入第二个文件。