非常感谢您花时间阅读本文。我对Perl还很陌生,所以对任何帮助表示赞赏!
我正在尝试使用正则表达式从大量大型文档中提取一段文本。
我有一个正则表达式,用于识别我想要开始提取的较大文档中的位置。此正则表达式的条件是,通常有多个实例与正则表达式匹配。我能够确定哪些匹配是我要提取的文本正文的开头。 (在下面的例子中,这将是$ finds [2]。
我想要做的是再次运行相同的正则表达式,并添加。*?$ END以提取$ END标识结尾的文本。但我需要的是一种告诉正则表达式在$ STAR的第N次出现时开始提取的方法。
考虑一下:
my $sentence = 'A1Z blah blah A2Z blah blah A3Z blah A4Z END A5Z';
my @finds = $sentence =~ m/(A\dZ)/mg;
####################
## Code that determine the element of @finds that
## contains the match to the extraction I want.
## For this question assume it is the third match (A3Z),
## Element index number 2.
####################
$START = 2;
以下是我的尝试:
my @finds2 = ($sentence =~ m/((A\dZ){$START}.*?(END))/mg);
my @finds2 = ($sentence =~ m/((A\dZ)[$START].*?(END))/mg);
如果{$ START}或[$ START]指示PERL要等到“$ START”匹配开始提取并继续匹配,我希望如此。
我知道我的尝试不正确。希望他们帮助表明我想要做的事情。
答案 0 :(得分:3)
这会做你喜欢的事吗?
my $pos = 3
my $END = "END";
my $a = "A1Z blah blah A2Z blah blah A3Z blah A4Z END A5Z";
$a =~ / (?:.*?A\dZ){$pos} (.*?) $END /x;
print $1, "\n" if defined $1;'
# prints " blah A4Z "
此代码将查找A \ dZ模式的第n次出现($pos
中指定的数字),然后开始保存到$1
,直到遇到$ END中的模式。如果确实需要性能,我建议您查看\G
断言,该断言将与您之前的匹配位置相匹配。这可以与内置的soubroutine pos
混合使用。防止“回溯”也可以提高性能,但这是一个我不太了解的高级主题。
推荐读物:“perlop - Regexp Quote-Like Operators”,“perlre - Assertions”和“perldoc -f pos”。
(另一种可能是将您的输入分成更小的字符串,但在许多情况下,最简单的Perl解决方案也是最好的。)