118

我有以下行,

typeName="ABC:xxxxx;";

我需要取词ABC

我写了以下代码片段,

Pattern pattern4=Pattern.compile("(.*):");
matcher=pattern4.matcher(typeName);

String nameStr="";
if(matcher.find())
{
    nameStr=matcher.group(1);

}

所以如果我放了group(0)我得到ABC:,但如果我放group(1)了它ABC,所以我想知道

  1. 这是什么0意思1?如果有人能用很好的例子解释我会更好。

  2. 正则表达式模式中包含 a :,那么为什么group(1)结果会忽略它呢?第 1 组是否检测到括号内的所有单词?

  3. 所以,如果我再多放两个括号,例如,\\s*(\d*)(.*):那么,会有两组吗?group(1)会退回(\d*)零件并group(2)退回(.*)零件吗?

给出代码片段的目的是为了消除我的困惑。这不是我正在处理的代码。上面给出的代码可以以String.split()更简单的方式完成。

4

3 回答 3

187

捕获和分组

捕获组 创建(pattern)具有捕获属性的组。

您可能经常看到(和使用)的一个相关是(?:pattern),它创建一个不捕获属性的,因此命名为非捕获组

当您需要重复一系列模式时,通常使用组,例如(\.\w+)+,或指定交替应在何处生效,例如^(0*1|1*0)$( ^, then0*11*0, then $) 与^0*1|1*0$(^0*11*0$)。

一个捕获组,除了分组之外,还会记录捕获组内的模式匹配的文本(pattern)。使用您的示例,(.*):匹配.*ABC匹配::并且由于.*在捕获组内,因此为捕获组 1 记录(.*)了文本。ABC

组号

整个模式定义为组号 0。

模式中的任何捕获组都从 1 开始索引。索引由捕获组的左括号的顺序定义。例如,以下模式中的所有5 个捕获组:

(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
|     |                       |          | |      |      ||       |     |
1-----1                       |          | 4------4      |5-------5     |
                              |          3---------------3              |
                              2-----------------------------------------2

组号用于\n模式和$n替换字符串中的反向引用。

在其他正则表达式风格(PCRE、Perl)中,它们也可以用于子例程调用

您可以使用 访问特定组匹配的文本Matcher.group(int group)。可以使用上述规则识别组号。

在某些正则表达式风格(PCRE、Perl)中,有一个分支重置功能,它允许您使用相同的数字捕获不同分支交替中的组

团队名字

从 Java 7 开始,您可以定义一个命名的捕获组 (?<name>pattern),并且您可以访问匹配的内容Matcher.group(String name)。正则表达式更长,但代码更有意义,因为它指示您尝试与正则表达式匹配或提取的内容。

\k<name>组名用于模式和${name}替换字符串中的反向引用。

命名的捕获组仍然使用相同的编号方案进行编号,因此它们也可以通过Matcher.group(int group).

在内部,Java 的实现只是从名称映射到组号。因此,您不能对 2 个不同的捕获组使用相同的名称。

于 2013-05-16T08:06:00.857 回答
99

对于我们其他人

这是一个简单明了的例子,说明了它是如何工作的:正则

( G1 )( G2 )( G3 )( G4 )( G5 )
表达式:([a-zA-Z0-9]+)([\s]+)([a-zA-Z ]+)([\s]+)([0-9]+)

细绳:"!* UserName10 John Smith 01123 *!"

group(0): UserName10 John Smith 01123
group(1): UserName10
group(2):  
group(3): John Smith
group(4):  
group(5): 01123

如您所见,我创建了五个组,每个组都用括号括起来。

我包括了 !* 和 *! 在任一侧使其更清晰。请注意,这些字符都不在 RegEx 中,因此不会在结果中生成。Group(0) 只为您提供整个匹配的字符串(我的所有搜索条件都在一行中)。第 1 组在第一个空格之前停止,因为搜索条件中未包含空格字符。第 2 组和第 4 组只是空白,在这种情况下实际上是空格字符,但也可以是制表符或换行符等。第 3 组包括空格,因为我将它放在搜索条件中......等等。

希望这是有道理的。

于 2014-12-06T05:47:10.273 回答
46

括号()用于启用正则表达式短语的分组。

group(1)包含括号之间的字符串,所以(.*).*这种情况下

group(0)包含整个匹配的字符串。

如果您有更多组(读取(...)),它将被放入具有下一个索引(2、3 等)的组中。

于 2013-05-13T08:29:14.490 回答