文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java正则表达式API字符类

2024-04-02 19:55

关注

一、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");
 
    assertEquals(matches, 3);
}

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

@Test
public void givenOneOrManyQuantifier_whenMatches_thenCorrect() {
    int matches = runTest("\\a+", "hi");
 
    assertFalse(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_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语法中至关重要。

到此这篇关于Java正则表达式API字符类的文章就介绍到这了,更多相关Java正则表达式 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯