2010-04-14 60 views
1

什么是单一的正则表达式,让我捕捉到 一切,从这个文本Perl的正则表达式提取部分

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

因此,我希望提取$1包含are genesis gene 之后进入文

A B C 
A 

试过,但失败:

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

你是否还需要避免非法字符串,如“......最好的基因是A”? – tiftik 2010-04-14 11:38:41

回答

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

+1用于尽可能接近地匹配请求者的示例,但是这可能会从某些信息中受益,这些信息解释了[s]与s相同,[s]本来就是他试图用它来完成的,那么?是等同的。 – kbenson 2010-04-14 17:24:56

2
$ perl -F/genes*/ -ane 'print $F[-1];' file 
A B C 
A 
2

使用非贪婪之初,以减少意外的机会。使用非捕获伙伴将您不关心的替代方法分组。将?附加到一封信使其成为可选项。因此,试试这个:

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

要看你错在哪里BTW,只是比较上面和你最初尝试。

+0

它捕捉到一些也是不好的语法的情况(“最接近的......是基因......”),但这并不重要,是的? :-) – 2010-04-14 11:25:44

+0

如果不重要,为什么还要打扰那个非捕获组? – SilentGhost 2010-04-14 11:33:07

+0

@SilentGhost:没有它,你会从单词“基因”的第一个实例捕获到最后,例如“最好的基因是A B C”。 – 2010-04-14 14:11:10

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]