在Perl中匹配最后一个正则表达式模式

3

我正在使用Perl编写脚本,并需要从文本文件中提取一些信息。

这是我的代码 - 字符串值是虚构的,但代表了所有可能的字符串变化。

my @alpha = ("abcdefgh(i) jklmno(pqrs3), uvwxyz", 
             "abcdefghi jklmn(opq1st), uvwxyz",
             "abcdefghi jklmn(o_q(1s3)), uvwxyz",
             "abcdef(gh)i jklmno(pq(1s3)), uvwxyz");

foreach my $line (@alpha){
    if ($line =~ /\((.*\(?.*\)?)\),/){
    print $1
    }
}

我正在尝试捕获最后一组括号(或方括号,对于英国英语使用者)中的大文本。
请注意,我使用“点”运算符,因为我想匹配任何内容,包括文本、数字或其他特殊字符。

基本上,我想打印出:

pqrs3
opq1st
o_q(1s3)
pq(1s3)

但是我一直收到以下错误信息:
 (i) jklmno(pqrs3) <-- not ok
 opq1st <-- this is ok
 opq(1s3) <-- this is also ok
 gh)i jklmno(pq(1s3) <-- not ok

我做错了什么?还是这种匹配方式根本不可能?
非常感谢您的帮助。

你总是想匹配最后一个外部匹配吗?你可能需要在这里使用解析器。请查看此SO文章 - Tim Biegeleisen
是的,我可以做到,并且不需要使用单行正则表达式。我曾尝试获取第一个括号和最后一个括号之间的所有内容,但效果并不理想。 - Sid5427
还有一个问题:你知道会有多少个括号分组吗?在你的示例中似乎是1-2个变化的。 - Tim Biegeleisen
你需要处理嵌套括号的递归正则表达式可能性。 - Tim Biegeleisen
@Borodin - 我所知道的是圆括号(),方括号[]和花括号{}(或大括号)...与美国的程序员交流时很容易混淆。 - Sid5427
显示剩余3条评论
2个回答

2

这是我见过的最优雅的正则表达式用法之一。谢谢。 我猜regex101链接也有表达式的描述吗? - Sid5427
@Sid5427 是的,它有 :) - vks
我有点困惑... 我试图去掉外面的括号.. (pq(1s3)) 变成 pq(1s3)... - Sid5427
@Sid5427,你可以轻松地从捕获的组中删除外部的 () - vks

2

这里提供一种使用给定字符串的方法:

use warnings;
use strict;

my @alpha = ("abcdefgh(i) jklmno(pqrs3), uvwxyz", 
             "abcdefghi jklmn(opq1st), uvwxyz",
             "abcdefghi jklmn(o_q(1s3)), uvwxyz",
             "abcdef(gh)i jklmno(pq(1s3)), uvwxyz");

foreach my $line (@alpha)
{
    if ( $line =~ m/.*\s+\w+\((.*)\),\s+\w+/ )
    {
        print $1, "\n";
    }
}

输出:

pqrs3
opq1st
o_q(1s3)
pq(1s3)

你所使用的间距作为锚点可能不是 OP 想要的。 - Miller
@Miller是正确的 - 我并不打算使用间距作为锚点,但现在看起来,它也是一个很好的替代方案。 - Sid5427

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接