2010-03-27 77 views
2

我不能明白爲什麼此代碼的工作:爲什麼在我的Perl正則表達式中捕獲積極的前瞻?

$seq = 'GAGAGAGA'; 
my $regexp = '(?=((G[UCGA][GA]A)|(U[GA]CG)|(CUUG)))'; # zero width match 
while ($seq =~ /$regexp/g){ # globally 
    my $pos = pos($seq) + 1; # position of a zero width matching 
    print "$1 position $pos\n"; 
} 

我知道這是一個零寬度匹配,並且它不到風度把匹配的字符串在$ &,但爲什麼它把它在$ 1嗎?

謝謝!

回答

2

您的正則表達式包含一個捕獲(...),這意味着$1,$2等變量將填充這些捕獲的結果。這也適用於向前看斷言(雖然不相信斷言,我相信)。

與所有捕獲一樣,如果您重寫爲(?:...),那麼內容將不會進入捕獲變量。

+0

沒有,它工作在回顧後了。 – ysth 2010-03-28 05:12:51

6

由於所有的內部括號,匹配被捕獲在$1中。如果你不想捕獲,然後使用

my $regexp = '(?=(?:(?:G[UCGA][GA]A)|(?:U[GA]CG)|(?:CUUG)))'; 

甚至更​​好

my $regexp = qr/(?=(?:(?:G[UCGA][GA]A)|(?:U[GA]CG)|(?:CUUG)))/; 

perlre documentation

  • (?:pattern)
  • (?imsx-imsx:pattern)

這是爲了羣集,而不是捕獲;它將子表達式分組爲(),但不會像()那樣進行反向引用。所以

@fields = split(/\b(?:a|b|c)\b/) 

就像

@fields = split(/\b(a|b|c)\b/) 

但不吐額外的字段。如果你不需要捕捉角色,也更便宜。

與一樣,?:之間的任何字母都充當標誌修飾符。例如,

/(?s-i:more.*than).*million/i 

等同於更復雜的

/(?:(?s-i)more.*than).*million/i 
相關問題