Совпадение с обратным переводом группы захвата в регулярном выражении Perl

Я пытаюсь найти строки, соответствующие определенному шаблону, а затем обратный перевод этого шаблона, за которым следует он, разделенный буквой O.

Правило перевода: /ABC/XYZ.

Пример совпадения: CCBAOXYZZ

Первый раздел соответствует шаблону [ABC]{3,25}. Затем есть буква O, которая также соответствует. Затем мы видим, что XYZZ является обратным значением CCBA с примененным выше переводом.

Мне удалось записать правило tr в мою обратную ссылку. Но я не могу понять, как сделать обратное.

while (my $input_string = <sample_input>) {
    push @hit, $1 while $input_string
        =~ m{
          (([ABC]{3,25})
          O
          (??{ $2 =~ tr/ABC/XYZ/r}))
        }xg;
}

Правильно ли добавить «обратную» функцию в третью строку регулярного выражения таким образом: (??{ $2 =~ tr/ACGT/TGCA/r;reverse}))?

Как сопоставить reverse tr из $2?


person bavudowi    schedule 19.04.2018    source источник


Ответы (1)


Ваш tr///r возвращает транслитерированную строку. Так что вам просто нужно вставить reverse перед tr///r, и все готово.

push @hit, $1 while $input_string
    =~ m{
      (([ABC]{3,25})
      O
      (??{ reverse $2 =~ tr/ABC/XYZ/r }))
    }xg;

Возвращаемое значение tr///r не входит в $_, поэтому ; reverse перевернет все, что находится в $_. Это делает общий матч провальным.

Вы сами ответили на свой вопрос в последнем предложении.

Как мне сопоставить обратную tr с $2?


Если вы добавите use re 'debug', вы сможете увидеть фактический совпадающий шаблон против.

С tr///; reverse вторая часть этого вывода отладки, относящаяся к регулярному выражению, скомпилированному из eval, выглядит следующим образом:

...
Compiling REx "ZZYXOABCC"
Final program:
   1: EXACT <ZZYXOABCC> (5)
   5: END (0)
anchored "ZZYXOABCC" at 0 (checking anchored isall) minlen 9 
Matching embedded REx "ZZYXOABCC" against "XYZZ"
...

Как мы видим здесь, он взял полную строку как вторую часть совпадения после O. Он правильно перевернул левую часть строки, но вернул всю строку.

Теперь, если мы сравним это с reverse tr///r, мы увидим разницу.

...
Compiling REx "XYZZ"
Final program:
   1: EXACT <XYZZ> (3)
   3: END (0)
anchored "XYZZ" at 0 (checking anchored isall) minlen 4 
Matching embedded REx "XYZZ" against "XYZZ"
...

Теперь он возвращает только транслитерированную левую часть строки, которая затем совпадает.

person simbabque    schedule 19.04.2018