2010-09-30 11 views
1
$ cat names 
projectname_flag_jantemp 
projectname_flag_febtemp 
projectname_flag_marchtemp 
projectname_flag_mondaytemp 
$ 

Perl代碼:如何在Perl中執行一般模式分配?

my $infile = "names"; 
open my $fpi, '<', $infile or die "$!"; 
while (<$fpi>) { 
    my $temp = # what should come here? # 
    func($temp); 
} 

我想溫度分別有

jan 
feb 
march 
monday 

模式始終保持不變

projectname_flag_<>temp 

怎麼辦提取?

回答

7
my ($temp) = /^projectname_flag_(.+)temp$/; 

注意,需要圍繞$temp括號,這樣的模式匹配列表中的上下文中運行。如果沒有他們,$temp最終只會包含一個真或假的值,指示匹配是否成功。

更一般地說,列表上下文中的模式匹配返回捕獲的子模式(如果匹配失敗,則返回空列表)。例如:

my $str = 'foo 123 456 bar'; 
my ($i, $j) = $str =~ /(\d+) +(\d+)/; # $i==123 $j==456 
+0

請記住檢查是否匹配成功。 – 2010-09-30 13:37:53

1
while (<$fpi>) { 
     chomp; 
     s{projectname_flag_(.*?)temp}{$1}; 
     # $_ will now have jan, feb, ... 
} 
+0

我怎樣才能讓一個變量,而不是'$ _'此操作?例如,輸入在'$ inp'而不是'$ _'中,輸出也應該到'$ out'而不是'$ _'? – Lazer 2010-09-30 12:32:03

+0

@Lazer:'($ out = $ inp)=〜s {projectname_flag _(。*?)temp} {$ 1};' – 2010-09-30 12:45:57

+0

或者,使用新的'/ r'標誌:http://www.effectiveperlprogramming.com/blog/659 ;-) – 2010-09-30 13:44:35

0

我想:

/^projectname_flag_([a-z]+)temp$/ 
0
while (<$fpi>) { 
    my ($temp) =($_ =~ m/projectname_flag_(.*?)temp/); 
    func($temp); 
} 
+0

+1爲非貪婪 – Axeman 2010-09-30 13:24:00

+0

-1當'。+'(或更嚴格的模式)更合適時使用'。*'。 – 2010-09-30 13:44:10

7

如果需要與舊perl兼容的操作系統,我會用FM's answer(只需確保通過,如果$month定義檢查成功的比賽)。

截至5.10,可以使用指定的捕獲:

my $month; 
if (/^ projectname _flag_ (?<month> [a-z]+) temp \z/x) { 
    $month = $+{month}; 
} 
+0

謝謝,我不知道命名捕獲。 – Lazer 2010-09-30 13:58:09