Regex Perl:如何在任意两个任意正则表达式之间查找项?

Regex Perl:如何在任意两个任意正则表达式之间查找项?,regex,perl,match,words,Regex,Perl,Match,Words,我试图在任意两个相同但任意的关键词之间找到并提取文本。例如,给定字符串: "aa bb aa cc 11 dd bb 11 cc" …我想得到: "aa bb aa" "bb aa cc 11 dd bb" "cc 11 dd bb 11 cc" "11 dd bb 11" 当我执行m/(\w+).+?($1)/操作时,或者当我使用“向前看”操作符时,似乎什么都不起作用,也找不到所有内容 三个问题: 您使用的是$1,但在正则表达式反引用中使用的是反斜杠,而不是美元符号:\1 您试图匹

我试图在任意两个相同但任意的关键词之间找到并提取文本。例如,给定字符串:

"aa bb aa cc 11 dd bb 11 cc"
…我想得到:

"aa bb aa"

"bb aa cc 11 dd bb"

"cc 11 dd bb 11 cc"

"11 dd bb 11"
当我执行
m/(\w+).+?($1)/
操作时,或者当我使用“向前看”操作符时,似乎什么都不起作用,也找不到所有内容

三个问题:

  • 您使用的是
    $1
    ,但在正则表达式反引用中使用的是反斜杠,而不是美元符号:
    \1

  • 您试图匹配整个单词,但您的正则表达式缺少单词边界

  • 你说你试过扮相,但你没说怎么做

您需要的正则表达式是:

(?=((\b\w+\b).+?(\b\2\b)))
您还需要添加
/g
标志,并在
while
循环中进行匹配,以获得所有结果:

my $subject = "aa bb aa cc 11 dd bb 11 cc";
while ($subject =~ m/(?=((\b\w+\b).+?(\b\2\b)))/g) {
    print "$1\n"
}
匹配项将
$1
,因为整个匹配都发生在前瞻中,这意味着
$&
将为空

这里有一个(Regex101.com),
和一个(Ideone.com)

三个问题:

  • 您使用的是
    $1
    ,但在正则表达式反引用中使用的是反斜杠,而不是美元符号:
    \1

  • 您试图匹配整个单词,但您的正则表达式缺少单词边界

  • 你说你试过扮相,但你没说怎么做

您需要的正则表达式是:

(?=((\b\w+\b).+?(\b\2\b)))
您还需要添加
/g
标志,并在
while
循环中进行匹配,以获得所有结果:

my $subject = "aa bb aa cc 11 dd bb 11 cc";
while ($subject =~ m/(?=((\b\w+\b).+?(\b\2\b)))/g) {
    print "$1\n"
}
匹配项将
$1
,因为整个匹配都发生在前瞻中,这意味着
$&
将为空

这里有一个(Regex101.com),

还有一个(Ideone.com)

如果我没弄错你的问题,你可以使用
(?{code})
模式和
(*失败)

结果似乎和您预期的一样:

$ perl test.pl
aa bb aa
bb aa cc 11 dd bb
cc 11 dd bb 11 cc
11 dd bb 11

如果我正确理解您的问题,您可以使用
(?{code})
模式和
(*失败)

结果似乎和您预期的一样:

$ perl test.pl
aa bb aa
bb aa cc 11 dd bb
cc 11 dd bb 11 cc
11 dd bb 11

我更喜欢非正则表达式的解决方案。下面的程序执行所需的操作

它首先将字符串拆分为项目,并将它们存储在数组
@items
中。哈希
%index
是一个哈希,它将每个不同的项与
@items
中出现的索引相关联,数组
@keys
是哈希的键,它们在
@terms
中出现的顺序。(如果输出顺序无关紧要,则不需要这样做。)

@terms
数组的子集针对包含两个或多个项的
%索引的每个值进行打印<代码>而
拼接一起使用
,以防有一个项目出现四次或四次以上,在这种情况下,输出将由第一次出现到第二次,第三次到第四次等组成。如果不需要这样做,则可以进一步简化程序

use strict;
use warnings 'all';

my $str = "aa bb aa cc 11 dd bb 11 cc";;
my @items = split ' ', $str;
my ( %indexes, @keys);

for my $i ( 0 .. $#items ) {
    my $key = $items[$i];
    push @keys, $key unless $indexes{$key};
    push @{ $indexes{$key} }, $i;
}

for my $key ( @keys ) {
    my @indexes = @{ $indexes{$key} };
    while ( @indexes >= 2 ) {
        my ( $beg, $end ) = splice @indexes, 0, 2;
        print "@items[$beg .. $end]\n";
    }
}
输出
aa-bb-aa
bb aa cc 11 dd bb
cc 11 dd bb 11 cc
11 dd bb 11

我更喜欢非正则表达式的解决方案。下面的程序执行所需的操作

它首先将字符串拆分为项目,并将它们存储在数组
@items
中。哈希
%index
是一个哈希,它将每个不同的项与
@items
中出现的索引相关联,数组
@keys
是哈希的键,它们在
@terms
中出现的顺序。(如果输出顺序无关紧要,则不需要这样做。)

@terms
数组的子集针对包含两个或多个项的
%索引的每个值进行打印<代码>而
拼接一起使用
,以防有一个项目出现四次或四次以上,在这种情况下,输出将由第一次出现到第二次,第三次到第四次等组成。如果不需要这样做,则可以进一步简化程序

use strict;
use warnings 'all';

my $str = "aa bb aa cc 11 dd bb 11 cc";;
my @items = split ' ', $str;
my ( %indexes, @keys);

for my $i ( 0 .. $#items ) {
    my $key = $items[$i];
    push @keys, $key unless $indexes{$key};
    push @{ $indexes{$key} }, $i;
}

for my $key ( @keys ) {
    my @indexes = @{ $indexes{$key} };
    while ( @indexes >= 2 ) {
        my ( $beg, $end ) = splice @indexes, 0, 2;
        print "@items[$beg .. $end]\n";
    }
}
输出
aa-bb-aa
bb aa cc 11 dd bb
cc 11 dd bb 11 cc
11 dd bb 11

您究竟是如何调用正则表达式的<代码>echo“11 dd bb 11”| perl-ne'/(\w+)+?($1)/;打印$1'对我来说很有用。不知道为什么这些答案被否决了。他们两个看起来对我都有用。echo“11 dd bb 11”| perl-lne“if($)/($)/){print“$1$2$3\n”;}”好吧,这只给了我“11”而没有其他任何东西。echo“11 dd bb 11”| perl-lne“if($)($)/($1)/){print“$1$2$3\n”}好吧,这只给了我“11”而没有其他东西。谢谢大家的帮助。非常感谢以上和以下评论!!!echo“11 dd bb 11”| perl-lne'if($|=~m/(\w+)(.+?)(\1)/){print“$1$2$3\n”;}”工作您究竟是如何调用正则表达式的<代码>echo“11 dd bb 11”| perl-ne'/(\w+)+?($1)/;打印$1'对我来说很有用。不知道为什么这些答案被否决了。他们两个看起来对我都有用。echo“11 dd bb 11”| perl-lne“if($)/($)/){print“$1$2$3\n”;}”好吧,这只给了我“11”而没有其他任何东西。echo“11 dd bb 11”| perl-lne“if($)($)/($1)/){print“$1$2$3\n”}好吧,这只给了我“11”而没有其他东西。谢谢大家的帮助。非常感谢以上和以下评论!!!echo“11 dd bb 11”| perl-lne'if($|=~m/(\w+)(\1/){print“$1$2$3\n”;}worksecho“aa bb aa cc 11 dd bb 11 cc”| perl-lne'if($|=~m/((\b\w++)(b\b\2\b))/g){print“$1--$2--$3\n”;}将为aa-bb aa--aa--aa--aa--aa--aa@lisprogtor. 如果您将
if
更改为
while
,您将获得所需的全部四个结果。我已经在我的答案中添加了一个Perl示例。echo“aa bb aa cc 11 dd bb 11 cc”| Perl-lne“如果($)=~m/(?=((\b\w++\b)。+(\b\2\b)))/g{print“$1--$2--$3\n”}将给您aa bb aa--aa--aa@lisprogtor. 如果您将
if
更改为
while
,您将获得所需的全部四个结果。我在回答中添加了一个Perl示例。({code})表示这是perl6,对吗?我快到下午六点了。perl6的固化程度如何,或者perl6的最终固化程度如何?它是perl5。T