无法让 Perl 正则表达式变得非贪婪

发布于 2024-12-20 08:34:54 字数 535 浏览 2 评论 0原文

无论我做什么,我的正则表达式都会匹配该行中的最后一组字母字符。我希望它只匹配第一次出现的情况。

我尝试过使用非贪婪运算符,但它顽固地匹配最右边的一组字母字符,在本例中为 $1 提供值“Trig”,这不是我想要的。我希望 $1 为“02.04.07.06 Geerite”。

代码

elsif ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*?)/)
{
    print OUTPUT "NT5 " . $1 . " | | \n";
}

来源

02.04.07.06 Geerite Cu8S5 R 3m、R 3m 或 R 32 Trig

输出

NT2 32 三角 | |

换句话说,我想要这个输出:

NT2 02.04.07.06 Geerite | |

My regex matches the last set of alpha characters in the line, regardless of what I do. I want it to match only the first occurrence.

I have tried using the non-greedy operator, but it stubbornly matches the right-most set of alpha characters, in this case giving $1 the value "Trig", which isn't what I want. I want $1 to be "02.04.07.06 Geerite".

Code

elsif ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*?)/)
{
    print OUTPUT "NT5 " . $1 . " | | \n";
}

Source

02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig

Output

NT2 32 Trig | |

So in other words, I want this output:

NT2 02.04.07.06 Geerite | |

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请远离我 2024-12-27 08:34:54

如果我将代码更改为

$line="     02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig ";
if ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*?)/) { print "NT5 ".$1." | | \n"; }

我会得到以下输出:

NT5 02.04.07.06  | | 

Making the * non-greedy,单词 Geerite 包含在输出中。

您观察到的输出可能来自 if-elsif-else 树的不同分支。

If I change your code to

$line="     02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig ";
if ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*?)/) { print "NT5 ".$1." | | \n"; }

I get this output:

NT5 02.04.07.06  | | 

Making the * non-greedy, the word Geerite is included in the output.

Your observed output probably comes from a different branch of the if-elsif-else tree.

甚是思念 2024-12-27 08:34:54

这应该适合您:

perl -e '$_ = "02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig"; print "$1\n" if /(\d\d\.\d\d\.\d\d\.\d\d \w+)/'

prints:

02.04.07.06 Geerite

正则表达式本身:

/(\d\d\.\d\d\.\d\d\.\d\d \w+)/

This should work for you:

perl -e '$_ = "02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig"; print "$1\n" if /(\d\d\.\d\d\.\d\d\.\d\d \w+)/'

prints:

02.04.07.06 Geerite

The regex on its own:

/(\d\d\.\d\d\.\d\d\.\d\d \w+)/
攒眉千度 2024-12-27 08:34:54

使 [[:alpha:]] 贪婪:

$line = '   02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig';
if ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*)/) {
    print OUTPUT "NT5 " . $1 . " | | \n";
}

输出

NT5 02.04.07.06 Geerite | |

Make [[:alpha:]] greedy:

$line = '   02.04.07.06 Geerite Cu8S5 R 3m, R 3m, or R 32 Trig';
if ($line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*)/) {
    print OUTPUT "NT5 " . $1 . " | | \n";
}

Output

NT5 02.04.07.06 Geerite | |
征棹 2024-12-27 08:34:54

您的正则表达式无法匹配“32 Trig”。一定还有其他问题。

如果我在示例字符串的开头添加一个空格并删除最后一个量词后面的不贪婪的 ? ,它将产生您想要的输出。

$line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*)/

[[:alpha:]]*? 将尽可能少地匹配,因此由于后面没有更多模式,它将匹配 0 个字符。

Your regex can't match " 32 Trig". There must be some other problem.

If I add a space at the beginning of your example string and remove the ungreedy ? after the last quantifier, it will produce the output you want.

$line =~ /\s(\d{2}\.\d{2}\.\d{2}\.\d{2}\s[[:alpha:]]*)/

The [[:alpha:]]*? will match as less as possible, so because there is no more pattern following, it will match 0 characters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文