2010-04-14 4 views
1

Что единственное регулярное выражение, которое позволяет мне захватить весь текст, который идет после are genes и is gene из этого текстаPerl экстракт регулярного выражения часть строки с множественным условием

The closest human genes of best are genes A B C 
The closest human gene of best is gene A 

Поэтому я надеюсь извлечь $1, которые содержат

A B C 
A 

попытался это, но не в состоянии:

$line =~ /The closest .* gene[s] (.*)$/; 
+0

Вам также нужно избегать незаконных строк, таких как «... ген лучших из них»? – tiftik

ответ

4
$line =~ /The closest .* genes? (.*)$/; 
+0

+1 для сопоставления примера подателя заявки как можно ближе, но это может извлечь выгоду из некоторой информации, объясняющей, что [s] совпадает с s, [s] было бы тем, что он пытался выполнить с этим, и это s? эквивалентно. – kbenson

2

Использование нежадным в начале, чтобы уменьшить возможности для сюрпризов. Используйте non-capture parens для группировки альтернатив, которые вам не нужны. Приложите ? к письму, чтобы сделать его необязательным. Следовательно, попробуйте следующее:

$line =~ /The closest .*? (?:is|are) genes? (.*)$/; 

Чтобы увидеть, где вы собираетесь неправильно BTW, просто сравните выше с тем, что вы изначально были попытки.

+0

Он захватывает некоторые случаи, которые также являются плохой грамматикой («Ближайшие ... это гены ...»), но это вряд ли важно, да? :-) –

+0

, если это не важно, зачем вообще беспокоиться о том, что группа, не связанная с захватом? – SilentGhost

+0

@SilentGhost: Без него вы будете захватывать из первого экземпляра слова «ген» до конца, например «лучшие из них - гены A B C». –

3

Я думаю, что наиболее явно это:

$line =~ m/best \s (?:is \s gene|are \s genes) \s ([\p{IsUpper}](?: \s [\p{IsUpper} ])*)/x; 

Конечно, если вы знаете, что все предложения будут грамматическими, то вы можете сделать (?:are|is) вещь. И если вы знаете, что у вас будут только гены A-N или что-то еще, вы можете забыть \p{IsUpper} и использовать [A-N].

Смежные вопросы