正则表达式:可选分组

4
我想要拆分这样的字符串:


abc//def//ghi

将内容分成第一次出现 // 之前和之后的部分:
a: abc
b: //def//ghi

我目前正在使用这个正则表达式:

(?<a>.*?)(?<b>//.*)

到目前为止,这个功能运行良好。

然而,有时源字符串中会缺少//,显然正则表达式无法匹配。如何使第二组可选?

abc这样的输入应该被匹配到:

a: abc
b: (empty)

我尝试了(?<a>.*?)(?<b>//.*)?,但在Expresso中得到了很多NULL结果,所以我想这不是正确的方法。

你确定你需要正则表达式吗? - SilentGhost
正则表达式可以很好地完成这个任务,没有理由不使用它。 - stevehipwell
正则表达式并非“必需品”。但在这种情况下,我喜欢使用正则表达式,因为上述只是更大的某些东西的简化部分,需要使用正则表达式。 - mafu
3个回答

8

在表达式开头加上^以匹配字符串开头,在末尾加上$以匹配字符串结尾(这将使非贪婪匹配生效)。

^(?<a>.*?)(?<b>//.*)?$

当我尝试这个时,我得到了一个单独的NULL结果。 - mafu
@mafutrct - 我没有通过 expresso 运行它,所以没有注意到非贪婪匹配,现在添加了 $ 来修复它。现在可以正确工作了。 - stevehipwell
有点晚了,但为什么非贪婪匹配只能在末尾添加$后才有效呢?我有一个类似的结构,当我让组 a 贪婪时,即 (?<a>.*),它会匹配整个字符串,并且可选组将永远不会被匹配(即使存在)。然而,当我让组 a 非贪婪时,正则表达式却什么也不匹配。请参见: https://regex101.com/r/TSqFUC/1。通过在组 a 中添加?来检查两个选项。但是,当添加 $ 时,非贪婪变体的正则表达式确实起作用。 - tobyvd
通过在正则表达式末尾添加 $,您强制贪婪组允许下一个组匹配它也可以作为整个正则表达式的一部分匹配到字符串末尾的字符。 - stevehipwell
@tobyvd,正则表达式中的贪婪模式优先于后面的可选模式。 - stevehipwell
显示剩余5条评论

0

Stevo3000的答案证明(Python):

import re

test_strings = ['abc//def//ghi', 'abc//def', 'abc']

regex = re.compile("(?P<a>.*?)(?P<b>//.*)?$")

for ts in test_strings:
    match = regex.match(ts)
    print 'a:', match.group('a'), 'b:', match.group('b')

a: abc b: //def//ghi
a: abc b: //def
a: abc b: None

-1

为什么要使用分组匹配呢?为什么不只是按"//"进行拆分,无论是作为正则表达式还是普通字符串?

use strict;

my $str = 'abc//def//ghi';
my $short = 'abc';

print "The first:\n";
my @groups = split(/\/\//, $str, 2);
foreach my $val (@groups) {
print "$val\n";
}

print "The second:\n";
@groups = split(/\/\//, $short, 2);
foreach my $val (@groups) {
print "$val\n";
}

提供

The first:
abc
def//ghi
The second:
abc

[编辑:已修复以返回最多2个组]


所有 // 位于第一个 // 之后的都将被忽略。 - mafu
我没听清楚。 我仍然认为我的解决方案是最容易理解的,可以使用大多数分割函数中存在的限制参数。 - gnud

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