如何将一组替换插入到Perl正则表达式中?

时间:2009-08-18 21:33:57

标签: regex perl

是否可以这样做:

@foo = getPileOfStrings();

if($text =~ /@foo(*.?)@foo/)
{
 print "Sweet, you grabbed a $1! It lived between the foos!";
}

这里发生的事情是我需要$text =~ /($var1|$var2|$var3)(*.?)($var1.../;我不知道有多少值,直到运行时我才知道这些值。

对一组OR进行数组插值似乎是直接的方法,但它看起来似乎不正常,而且我正在进入一组曲折的代码......它们都是一样的!

2 个答案:

答案 0 :(得分:11)

使用joinqr//运算符:

my $strings = join "|", getPileOfStrings();
my $re      = qr/$strings/; #compile the pattern

if ($text =~ /$re(*.?)$re/)

如果你希望同一个词分隔中间的东西说:

if ($text =~/($re)(.*?)\1/)

如果字符串可能包含Perl regexes认为特殊的字符,您可能需要使用mapquotemeta来阻止它们被正则表达式使用:

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;