正则表达式可选分组

128

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

((?:[a-z][a-z]+))_(\d+)_((?:[a-z][a-z]+)\d+)_(\d{13})

匹配像这样的字符串:

SH_6208069141055_BC000388_20110412101855

分为4组:

SH
6208069141055
BC000388
20110412101855

问题:如何使第一组可选,以便结果组为空字符串?
我希望在所有情况下都能获得4个组。

此案例的输入字符串:(第一组后没有下划线)

6208069141055_BC000388_20110412101855
2个回答

220

如果想创建一个非捕获的、零个或多个匹配的分组,需要在末尾添加?

(?: ..... )?
^          ^____ optional
|____ group

1
选项组和(...)之间有什么区别? - Golden Lion
1
@GoldenLion ? 匹配 "零次或一次",而 * 匹配 "零次或多次"。 - Daniel W.
4
在组的开头,?: 是什么意思? - brobers
3
@brobers 一个普通的组(...)将捕获结果中的内容,但是(?:...)使其成为非捕获组,因此它必须匹配(或应用),但不会包含在结果组中。 - Daniel W.

97

您可以轻松地将正则表达式简化为以下内容:

(?:([a-z]{2,})_)?(\d+)_([a-z]{2,}\d+)_(\d+)$
^              ^^
|--------------||
| first group  ||- quantifier for 0 or 1 time (essentially making it optional) 

我不确定删除第一组后输入的字符串是否会有下划线,但如果要匹配整个字符串,您可以使用上面的正则表达式。

regex101演示

如您所见,在第二次匹配中匹配的第一组为空,并从匹配的第二组开始。


1
哪个字符标记了可选组? - Daniel W.
2
第一个组后面的 ??那是从左边数起的第17个字符。 - Jerry

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