2009-06-02 34 views
1

我想構建一個正則表達式來搜索和替換文件。以下是腳本。正則表達式的搜索和編輯構造

#!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」的正則表達式。我知道程序執行是因爲它打印出'到達此處'。任何人都可以提出

  1. 爲什麼使用我 指定正則表達式我的程序無法 搜索字符串。
  2. 爲什麼我的系統無法識別 「\ s」和給錯誤「無法識別的 逃避\ S通過在 測試通過」
  3. 並且還,任何人都可以提出對學習正則表達式的一些 良好來源。

感謝

+0

查看http://stackoverflow.com/questions/934733/perl-loop-through-a-file-and-substitute/934756#934756如果你只是想要一個oneliner – 2009-06-02 15:22:49

+0

另一種說法是「[^ a-zA -Z0-9]「是」\ P {IsAlnum}「 – Axeman 2009-06-02 18:07:14

回答

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 

學習rege的好資源XES是:

0

你打開追加模式一個文件,然後試圖讀取和寫入它。可以讀取和寫入文件,但您需要使用不同的模式。但除非你想要替換完全相同數量的字符,否則你將不得不從一個文件中讀取數據,並將所有內容(包括已更改和未更改的部分)寫入第二個文件。