是否可以这样做:
@foo = getPileOfStrings();
if($text =~ /@foo(*.?)@foo/)
{
print "Sweet, you grabbed a $1! It lived between the foos!";
}
这里发生的事情是我需要$text =~ /($var1|$var2|$var3)(*.?)($var1.../
;我不知道有多少值,直到运行时我才知道这些值。
对一组OR进行数组插值似乎是直接的方法,但它看起来似乎不正常,而且我正在进入一组曲折的代码......它们都是一样的!
答案 0 :(得分:11)
my $strings = join "|", getPileOfStrings();
my $re = qr/$strings/; #compile the pattern
if ($text =~ /$re(*.?)$re/)
如果你希望同一个词分隔中间的东西说:
if ($text =~/($re)(.*?)\1/)
如果字符串可能包含Perl regexes认为特殊的字符,您可能需要使用map
和quotemeta
来阻止它们被正则表达式使用:
my $strings = join "|", map quotemeta, getPileOfStrings();
而且,正如Michael Carman指出的那样,如果getPileOfStrings()
不是按照您希望匹配的顺序返回字符串,那么您可能希望使用sort
来强制进行最长时间的匹配在交替中成为第一个(交替中较早的项目将在Perl 5中首先匹配):
my $strings = join "|" map quotemeta,
sort { length $a <=> length $b } getPileOfStrings();
请记住在运行quotemeta之前进行排序,因为"a..."
(长度4)将转换为"a\\.\\.\\."
(长度6),其长度超过"aaaaaa"
(长度5)。
答案 1 :(得分:4)
您可以使用Regex::PreSuf:
my $re = presuf(getPileOfStrings());
在开始之前,您可能想要考虑以下代码的作用:
#!/usr/bin/perl
use strict;
use warnings;
my @pile = qw(ar a);
my $string = 'ar5a';
my $pile = join '|', @pile;
my $re = qr/$pile/;
my ($captured) = $string =~ /$re(.*?)$re/;
print "$captured\n";
如果您希望$captured
包含"r5"
,请在加入之前按其元素的长度排序@pile
my $pile = join '|', sort { length $a <=> length $b } @pile;