Java正则表达式API边界匹配

目录
  • Boundary Matchers
  • Pattern Class Methods
    • Pattern.CANON_EQ
    • Pattern.CASE_INSENSITIVE
    • Pattern.COMMENTS

Boundary Matchers

Java regex API还支持边界匹配。如果我们关心在输入文本中匹配的确切位置,那么这就是我们要寻找的。在前面的示例中,我们关心的只是是否找到匹配项。

为了仅在文本开头所需的正则表达式为true时匹配,我们使用插入符号^。

此测试将失败,因为可以在开头找到文本dog:

@Test
public void givenText_whenMatchesAtBeginning_thenCorrect() {
    int matches = runTest("^dog", "dogs are friendly");

    assertTrue(matches > 0);
}

下面的测试将失败:

@Test
public void givenTextAndWrongInput_whenMatchFailsAtBeginning_
  thenCorrect() {
    int matches = runTest("^dog", "are dogs are friendly?");

    assertFalse(matches > 0);
}

为了仅在文本末尾所需的正则表达式为true时匹配,我们使用美元字符$。在以下情况下会找到匹配项:

@Test
public void givenText_whenMatchesAtEnd_thenCorrect() {
    int matches = runTest("dog$", "Man's best friend is a dog");

    assertTrue(matches > 0);
}

并且没有找到匹配:

@Test
public void givenTextAndWrongInput_whenMatchFailsAtEnd_thenCorrect() {
    int matches = runTest("dog$", "is a dog man's best friend?");

    assertFalse(matches > 0);
}

如果仅在单词边界处找到所需文本时才需要匹配,则在正则表达式的开头和结尾使用\\b正则表达式:

空格是单词边界:

@Test
public void givenText_whenMatchesAtWordBoundary_thenCorrect() {
    int matches = runTest("\\bdog\\b", "a dog is friendly");

    assertTrue(matches > 0);
}

行首的空字符串也是单词边界:

@Test
public void givenText_whenMatchesAtWordBoundary_thenCorrect2() {
    int matches = runTest("\\bdog\\b", "dog is man's best friend");

    assertTrue(matches > 0);
}

这些测试之所以通过,是因为字符串的开头以及文本之间的空格标记了单词边界,但是以下测试显示了相反的结果:

@Test
public void givenWrongText_whenMatchFailsAtWordBoundary_thenCorrect() {
    int matches = runTest("\\bdog\\b", "snoop dogg is a rapper");

    assertFalse(matches > 0);
}

一行中出现的两个单词字符不会标记单词边界,但我们可以通过更改正则表达式的结尾来查找非单词边界:

@Test
public void givenText_whenMatchesAtWordAndNonBoundary_thenCorrect() {
    int matches = runTest("\\bdog\\B", "snoop dogg is a rapper");
    assertTrue(matches > 0);
}

Pattern Class Methods

之前,我们只以基本方式创建了模式对象。然而,这个类有另一个compile方法的变体,它接受一组标志以及影响模式匹配方式的regex参数。

这些标志只是抽象的整数值。让我们重载test类中的runTest方法,以便它可以将标志作为第三个参数:

public static int runTest(String regex, String text, int flags) {
    pattern = Pattern.compile(regex, flags);
    matcher = pattern.matcher(text);
    int matches = 0;
    while (matcher.find()){
        matches++;
    }
    return matches;
}

在本节中,我们将了解不同的支持标志以及它们的使用方式。

Pattern.CANON_EQ

此标志启用canonical equivalence,当且仅当两个字符的完整规范分解匹配时,才会认为这两个字符匹配。

考虑带重音的Unicode字符é。它的复合代码点是u00E9。但是,Unicode的组成字符eu0065u0301也有单独的代码点。在这种情况下,合成字符u00E9与双字符序列u0065 u0301无法区分。

默认情况下,匹配不考虑规范等效:

@Test
public void givenRegexWithoutCanonEq_whenMatchFailsOnEquivalentUnicode_thenCorrect() {
    int matches = runTest("\u00E9", "\u0065\u0301");

    assertFalse(matches > 0);
}

但如果添加标志,则测试将通过:

@Test
public void givenRegexWithCanonEq_whenMatchesOnEquivalentUnicode_thenCorrect() {
    int matches = runTest("\u00E9", "\u0065\u0301", Pattern.CANON_EQ);

    assertTrue(matches > 0);
}

Pattern.CASE_INSENSITIVE

无论大小写,此标志都支持匹配。默认情况下,匹配会考虑大小写:

@Test
public void givenRegexWithDefaultMatcher_whenMatchFailsOnDifferentCases_thenCorrect() {
    int matches = runTest("dog", "This is a Dog");

    assertFalse(matches > 0);
}

因此,使用此标志,我们可以更改默认行为:

@Test
public void givenRegexWithCaseInsensitiveMatcher
  _whenMatchesOnDifferentCases_thenCorrect() {
    int matches = runTest(
      "dog", "This is a Dog", Pattern.CASE_INSENSITIVE);

    assertTrue(matches > 0);
}

我们还可以使用等效的嵌入标志表达式来实现相同的结果:

@Test
public void givenRegexWithEmbeddedCaseInsensitiveMatcher
  _whenMatchesOnDifferentCases_thenCorrect() {
    int matches = runTest("(?i)dog", "This is a Dog");

    assertTrue(matches > 0);
}

Pattern.COMMENTS

Java API允许在正则表达式中包含使用#的注释。这有助于记录复杂的正则表达式,而其他程序员可能无法立即看到这些正则表达式。

comments标志使matcher忽略正则表达式中的任何空白或注释,只考虑模式。

在默认匹配模式下,以下测试将失败:

@Test
public void givenRegexWithComments_whenMatchFailsWithoutFlag_thenCorrect() {
    int matches = runTest(
      "dog$  #check for word dog at end of text", "This is a dog");

    assertFalse(matches > 0);
}

这是因为匹配器将在输入文本中查找整个正则表达式,包括空格和#字符。但当我们使用该标志时,它将忽略额外的空格,并且以#开头的每个文本都将被视为每行要忽略的注释:

@Test
public void givenRegexWithComments_whenMatchesWithFlag_thenCorrect() {
    int matches = runTest(
      "dog$  #check end of text","This is a dog", Pattern.COMMENTS);

    assertTrue(matches > 0);
}

还有一个替代的嵌入式标志表达式:

@Test
public void givenRegexWithComments_whenMatchesWithEmbeddedFlag_thenCorrect() {
    int matches = runTest(
      "(?x)dog$  #check end of text", "This is a dog");

    assertTrue(matches > 0);
}

到此这篇关于Java正则表达式API边界匹配的文章就介绍到这了,更多相关Java正则表达式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 如何在Java中使用正则表达式API

    目录 Java正则表达式包 简单的例子 Meta Characters元字符 Character类 OR NOR Range类 Union类 Intersection类 Subtraction类 前言: 在正则表达式的世界中,有许多不同的风格可供选择,比如grep.Perl.Python.PHP.awk等等.这意味着在一种编程语言中工作的正则表达式可能在另一种编程语言中不工作.Java中的正则表达式语法与Perl中的最相似.要在Java中使用正则表达式,我们不需要任何特殊设置.JDK包含一个特殊

  • Java正则表达式API字符类

    目录 一.Predefined字符类 二.Quantifiers 三.Capturing Groups 一.Predefined字符类 Java正则表达式API也接受预定义的字符类.上面的一些字符类可以用更短的形式表示,尽管这会降低代码的直观性.这个正则表达式的Java版本的一个特殊方面是转义字符. 正如我们将看到的,大多数字符都以反斜杠开头,这在Java中有特殊的意义.对于要由模式类编译的这些,必须转义前导反斜杠,即.\d变为\\d. 匹配的数字,相当于[0-9]: @Test public

  • Java API学习教程之正则表达式详解

    前言 正则表达式是什么应该不用过多介绍,每位程序员应该都知道,正则表达式描述的是一种规则,符合这种限定规则的字符串我们认为它某种满足条件的,是我们所需的.在正则表达式中,主要有两种字符,一种描述的是普通的字符,另一种描述的是元字符.其中元字符是整个正则表达式的核心,并由它完成规则的制定工作. 本篇文章主要从Java这门程序设计语言的角度理解正则表达式的应用,主要涉及以下内容: •基本正则表达式的理论基础 •Java中用于正则表达式匹配的类 •几种常用的正则表达式使用实例 一.正则表达式的理论基础

  • Java正则表达式API边界匹配

    目录 Boundary Matchers Pattern Class Methods Pattern.CANON_EQ Pattern.CASE_INSENSITIVE Pattern.COMMENTS Boundary Matchers Java regex API还支持边界匹配.如果我们关心在输入文本中匹配的确切位置,那么这就是我们要寻找的.在前面的示例中,我们关心的只是是否找到匹配项. 为了仅在文本开头所需的正则表达式为true时匹配,我们使用插入符号^. 此测试将失败,因为可以在开头找到

  • Java正则表达式API Matcher类方法

    目录 一.Pattern.DOTALL 二.Pattern.LITERAL 三.Pattern.MULTILINE 四.Matcher类方法 索引方法 Study方法 Replacement方法 一.Pattern.DOTALL 默认情况下,当我们使用“.”时表达式中,我们将匹配输入字符串中的每个字符,直到遇到新行字符. 使用此标志,匹配也将包括行终止符.我们将通过以下示例更好地理解.这些例子将略有不同.由于我们感兴趣的是针对匹配的字符串进行断言,因此我们将使用matcher的group方法来返

  • java正则表达式四种常用的处理方式(匹配、分割、替代、获取)

    java 正则表达式高级篇,介绍四种常用的处理方式:匹配.分割.替代.获取,具体内容如下 package test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 正则表达式 * 正则表达式 的用法主要是4种方面的使用 * 匹配,分割,替换,获取. * 用一些简单的符号来代表代码的操作 * @author cyc * */ public class Rex { public static void ma

  • Java基于正则表达式实现查找匹配的文本功能【经典实例】

    本文实例讲述了Java基于正则表达式实现查找匹配的文本功能.分享给大家供大家参考,具体如下: REMatch.java: package reMatch; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by Frank */ public class REMatch { public static void main(String[] args) { String patt = "Q[^

  • Java正则表达式实现在文本中匹配查找换行符的方法【经典实例】

    本文实例讲述了Java正则表达式实现在文本中匹配查找换行符的方法.分享给大家供大家参考,具体如下: 默认情况下,正则表达式 ^ 和 $ 忽略行结束符,仅分别与整个输入序列的开头和结尾匹配.如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配.处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配. NLMatch.java: package nlMatch; import java.util.regex.Pattern; /**

  • Java正则表达式匹配电话格式

    大家都知道,正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它用以描述在查找文字主体时待匹配的一个或多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配. /** * 手机号:目前全国有27种手机号段. * 移动有16个号段:134.135.136.137.138.139.147.150.151.152.157.158.159.182.187.188.其中147.157.188是3G号段,其

  • 学习Java正则表达式(匹配、替换、查找)

    本文为大家分享了Java正则表达式的匹配.替换.查找和切割操作,有兴趣的朋友可以参考一下 import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class test { public static void main(String[] args) { getStrings(); //用正则表达式获取指定字符串内容中的指定内容 System.out.pri

  • Java正则表达式如何匹配特定html标签内的内容

    如题: 使用正则表达式,怎么匹配特定html标签内的内容. 比如,对于如下文本串: ... ignored content prefix content <html>inner content</html> postfix content ... ignored content 我们要提取出<html>标签内的内容: inner content(这里的html标签可以换成任何其它的标签,比如<p>标签) 这里引入正则表达式的group概念:详细点击文章查看

随机推荐