Java正则表达式API字符类

网友投稿 310 2022-07-25


目录一、Predefined字符类二、Quantifiers三、Capturing Groups

一、Predefined字符类

java正则表达式API也接受预定义的字符类。上面的一些字符类可以用更短的形式表示,尽管这会降低代码的直观性。这个正则表达式的Java版本的一个特殊方面是转义字符。

正如我们将看到的,大多数字符都以反斜杠开头,这在Java中有特殊的意义。对于要由模式类编译的这些,必须转义前导反斜杠,即.\d变为\\d。

匹配的数字,相当于[0-9]:

@Test

public void givenDigits_whenMatches_thenCorrect() {

int matches = runTest("\\d", "123");

assertEquals(matches, 3);

}

匹配非数字,相当于[^0-9]:

@Test

public void givenNonDigits_whenMatches_thenCorrect() {

int mathces = runTest("\\D", "a6c");

assertEquals(matches, 2);

}

匹配空白:

@Test

public void givenWhiteSpace_whenMatches_thenCorrect() {

int matches = runTest("\\s", "a c");

assertEquals(matches, 1);

}

匹配非空白:

@Test

public void givenNonWhiteSpace_whenMatches_thenCorrect() {

int matches = runTest("\\S", "a c");

assertEquals(matches, 2);

}

匹配一个单词字符,相当于[a-zA-Z_0-9]:

@Test

public void givenWordCharacter_whenMatches_thenCorrect() {

int matches = runTest("\\w", "hi!");

assertEquals(matches, 2);

}

匹配非单词字符:

@Test

public void givenNonWordCharacter_whenMatches_thenCorrect() {

int matches = runTest("\\W", "hi!");

assertEquals(matches, 1);

}

二、Quantifiers

Java正则表达式API还允许我们使用Quantifiers。通过指定匹配的出现次数,我们可以进一步调整匹配的行为。

要匹配零次或一次文本,我们使用?量词:

@Test

public void givenZeroOrOneQuantifier_whenMatches_thenCorrect() {

int matches = runTest("\\a?", "hi");

assertEquals(matches, 3);

}

或者,我们可以使用大括号语法,Java regex API也支持这种语法:

@Test

public void givenZeroOrOneQuantifier_whenMatches_thenCorrect2() {

int matches = runTest("\\a{0,1}", "hi");

assertEquals(matches, 3);

}

本例介绍了零长度匹配的概念。碰巧的是,如果一个量词的匹配阈值为零,它总是匹配文本中的所有内容,包括每个输入末尾的一个空字符串。这意味着即使输入为空,它也将返回一个零长度匹配。

这就解释了为什么在上面的示例中,尽管字符串长度为2,但我们仍得到3个匹配项。第三个匹配项是长度为零的空字符串。

为了匹配零次或无限次的文本,我们使用*量词,它与?:

@Test

public void givenZeroOrManyQuantifier_whenMatches_thenCorrect() {

int matches = runTest("\\a*", "hi");

assertEquals(matches, 3);

}

支持的替代方案:

@Test

public void givenZeroOrManyQuantifier_whenMatches_thenCorrect2() {

int matches = runTest("\\a{0,}", "hi");sHCjLRlca

assertEquals(matches, 3);

}

差异量词为+,匹配阈值为1。如果所需的字符串根本不出现,则将不存在匹配项,甚至不存在长度为零的字符串:

@Test

public void givenOneOrManyQuantifier_whenMatches_thenCorrect() {

int matches = runTest("\\a+", "hi");

ahttp://ssertFalse(matches);

}

支持的替代方案:

@Test

public void givenOneOrManyQuantifier_whenMatches_thenCorrect2() {

int matches = runTest("\\a{1,}", "hi");

assertFalse(matches);

}

正如在Perl和其他语言中一样,大括号语法可用于多次匹配给定文本:

@Test

public void givenBraceQuantifier_whenMatches_thenCorrect() {

int matches = runTest("a{3}", "aaaaaa");

assertEquals(matches, 2);

}

在上面的例子中,我们得到了两个匹配项,因为只有当a在一行中出现三次时,才会出现匹配项。但是,在下一次测试中,我们不会得到匹配,因为文本在一行中只出现两次:

@Test

public void givenBraceQuantifier_whenFailsToMatch_thenCorrect() {

int matches = runTest("a{3}", "aa");

assertFalse(matches > 0);

}

当我们在大括号中使用范围时,匹配将是贪婪的,从范围的高端匹配:

@Test

public void givenBraceQuantifierWithRange_whenMatches_thenCorrect() {

int matches = runTest("a{2,3}", "aaaa");

assertEquals(matches, 1);

}

我们已经指定了至少两次但不超过三次,所以我们得到一个匹配,匹配者看到一个aaa和一个无法匹配的a。

然而,API允许我们指定一种懒惰或不情愿的方法,以便匹配器可以从范围的低端开始,在这种情况下,匹配两个匹配项aa和aa:

@Test

public void givenBraceQuantifierWithRange_whenMatchesLazily_thenCorrect() {

int matches = runTest("a{2,3}?", "aaaa");

assertEquals(matches, 2);

}

三、Capturing Groups

API还允许我们通过Capturing Groups将多个角色视为一个单元。它会将数字附加到Capturing Groups,并允许使用这些数字进行反向引用。

在本节中,我们将看到一些关于如何在Java正则表达式API中使用Capturing Groups的示例。

让我们使用一个仅当输入文本包含两个相邻数字时才匹配的Capturing Groups:

@Test

public void givenCapturingGroup_whenMatches_thenCorrect() {

int maches = runTest("(\\d\\d)", "12");

assertEquals(matches, 1);

}

上面匹配的数字是1,使用back引用告诉匹配者我们想要匹配文本匹配部分的另一个匹配项。这样做,而不是:

@Test

public void givenCapturingGroup_whenMatches_thenCorrect2() {

int matches = runTest("(\\d\\d)", "1212");

assertEquals(matches, 2);

}

如果输入有两个单独的匹配项,我们可以有一个匹配项,但使用反向引用传播相同的正则表达式匹配项以跨越输入的整个长度:

@Test

public void givenCapturingGroup_http://whenMatchesWithBackReference_

thenCorrect() {

int matches = runTest("(\\d\\d)\\1", "1212");

assertEquals(matches, 1);

}

我们必须重复正则表达式,而无需反向引用,才能获得相同的结果:

@Test

public void givenCapturingGroup_whenMatches_thenCorrect3() {

int matches = runTest("(\\d\\d)(\\d\\d)", "1212");

assertEquals(matches, 1);

}

类似地,对于任何其他重复次数,反向引用可以使匹配者将输入视为单个匹配:

@Test

public void givenCapturingGroup_whenMatchesWithBackReference_

thenCorrect2() {

int matches = runTest("(\\d\\d)\\1\\1\\1", "12121212");

assertEquals(matches, 1);

}

但如果你甚至改变了最后一个数字,匹配就会失败:

@Test

public void givenCapturingGroupAndWrongInput_

whenMatchFailsWithBackReference_thenCorrect() {

int matches = runTest("(\\d\\d)\\1", "1213");

assertFalse(matches > 0);

}

重要的是不要忘记转义反斜杠,这在Java语法中至关重要。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java代码实现简单酒店管理系统
下一篇:Java利用EasyExcel实现合并单元格
相关文章

 发表评论

暂时没有评论,来抢沙发吧~