Почему позитивный взгляд приводит к захватам в моем регулярном выражении Perl? - PullRequest
2 голосов
/ 27 марта 2010

Я не могу понять, почему этот код работает:

$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 ]

6 голосов
/ 27 марта 2010

Совпадения фиксируются в $1 из-за всех внутренних скобок. Если вы не хотите снимать, используйте

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

или даже лучше

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

Из документации perlre :

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

Это для кластеризации, а не захвата; он группирует подвыражения как (), но не делает обратных ссылок, как (). Так

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

похоже на

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

но не выдает дополнительных полей. Также дешевле не захватывать персонажей, если вам это не нужно.

Любые буквы от ? до : действуют как модификаторы флагов, как и (?imsx-imsx). Например,

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

эквивалентно более многословному

/(?:(?s-i)more.*than).*million/i
2 голосов
/ 27 марта 2010

Ваше регулярное выражение содержит захват (...), что означает, что переменные $1, $2 и т. Д. Будут заполнены результатами этих захватов. Это работает и в косвенных утверждениях (хотя, я полагаю, не в предвкушении утверждений).

Как и во всех перехватах, если вы переписываете как (?:...), то содержимое не попадет в переменную перехвата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...