2016-11-18 14 views
2

我有一個字符串,例如獲得重複的正則表達式匹配

my $str = "Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake" 

我有一些字符串我想,以滿足他們的名字和文本,直到下一場比賽,所以我目前正在

my $re = "(Dave|Sally|Fred|John|Wilma)" # created dynamically 

我可以反覆做像

比賽
my @matches; 
push @matches, [$1, $2] while $str =~ /$re/g; 
warn Dumper @matches; 

不知道我會放拉出$ 2

這將抓住匹配,但我想找到一種方法來匹配中間部分直到下一個匹配,所以理想情況下我最終會得到類似的東西(不關心它的數組,哈希或任何)。

[["Dave"," birthday on 11/12/68"], 
["Fred"," enjoys cooking"], 
["Wilma"," likes cake"]] 

我也許可以通過分割字符串匹配的位置和剩餘做到這一點,但我想知道是否有我缺少任何明顯的正則表達式的方法是什麼?

+0

我想上的名字拆分像這樣'我的(民主,@foo)=分流/ $ RE /,$海峽; '並擺脫第一個空串(來自_Dave_的LHS)。 – simbabque

+0

謝謝,這很有用,有沒有辦法將匹配的名字與該方法一起推送? – Ian

回答

3

使用預讀斷言,以便下一個搜索在結束上一個搜索的名稱之前開始。

#! /usr/bin/perl 
use warnings; 
use strict; 
use feature 'say'; 

my $str = 'Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake'; 
my $names_re = qr/Dave|Sally|Fred|John|Wilma/; 
my $re = qr/($names_re) (.*?)(?= $names_re|$)/; 

my @matches; 
push @matches, [ $1, $2 ] while $str =~ /$re/g; 

use Data::Dumper; print Dumper \@matches; 
+1

如果你的Perl至少是5.22,你也可以在本地使用'/ n'修飾符,所以你不需要從像這樣的問題中去掉原來的'$ re'中的名字組:'while $ str =〜/ $ re(。*?)(?n:(?= $ re | $))/ g'。它將關閉預測內的捕獲。見http://perldoc.perl.org/perlre.html#*n* – simbabque

+0

超級,非常感謝。 – Ian

1

使用split與捕獲組以產生哈希:

#!/usr/bin/perl 
use warnings; 
use strict; 
use Data::Dumper qw(Dumper); 

my $str = 'Dave birthday on 11/12/68 Fred enjoys cooking Wilma likes cake'; 
my $names_re = qr/(Dave|Sally|Fred|John|Wilma)/; 

my @parts = split /\s*\b$names_re\b\s*/, $str; 
shift @parts; 
my %result = @parts; 

print Dumper \%result; 
+0

我喜歡這個答案,感覺我的頭腦稍微容易跟隨。與前瞻性答案相比,不確定是否有任何優點和缺點,但會給他們兩個測試。非常感謝。 – Ian