系列中的上一篇
当前教程
Pattern 类
系列中的下一篇

系列中的上一篇: 边界

系列中的下一篇: Matcher 类

Pattern 类

 

使用标志创建模式

Pattern 类定义了一种接受一组影响模式匹配方式的标志的备用编译方法。flags 参数是一个位掩码,可以包含以下任何公共静态字段

  • Pattern.CANON_EQ 启用规范等效性。当指定此标志时,只有当两个字符的完整规范分解匹配时,才会认为它们匹配。例如,表达式 "a\u030A" 在指定此标志时将匹配字符串 "\u00E5"。默认情况下,匹配不考虑规范等效性。指定此标志可能会降低性能。
  • Pattern.CASE_INSENSITIVE 启用不区分大小写的匹配。默认情况下,不区分大小写的匹配假设只匹配 US-ASCII 字符集中的字符。可以通过与该标志一起指定 UNICODE_CASE 标志来启用 Unicode 意识的不区分大小写的匹配。不区分大小写的匹配也可以通过嵌入式标志表达式 (?i) 启用。指定此标志可能会略微降低性能。
  • Pattern.COMMENTS 允许模式中的空格和注释。在此模式下,空格将被忽略,从 # 开始的嵌入式注释将被忽略,直到行尾。注释模式也可以通过嵌入式标志表达式 (?x) 启用。
  • Pattern.DOTALL 启用 dotall 模式。在 dotall 模式下,表达式 . 匹配任何字符,包括行终止符。默认情况下,此表达式不匹配行终止符。dotall 模式也可以通过嵌入式标志表达式 (?s) 启用。(s 是“单行”模式的助记符,这就是 Perl 中的称呼。)
  • Pattern.LITERAL 启用模式的字面解析。当指定此标志时,指定模式的输入字符串将被视为一系列字面字符。输入序列中的元字符或转义序列将不会被赋予任何特殊含义。标志 Pattern.CASE_INSENSITIVEPattern.UNICODE_CASE 在与该标志一起使用时,会保留它们对匹配的影响。其他标志变得多余。没有用于启用字面解析的嵌入式标志字符。
  • Pattern.MULTILINE 启用多行模式。在多行模式下,表达式 ^$ 分别匹配行终止符或输入序列结束后的位置。默认情况下,这些表达式只匹配整个输入序列的开头和结尾。多行模式也可以通过嵌入式标志表达式 (?m) 启用。
  • Pattern.UNICODE_CASE 启用 Unicode 意识的大小写折叠。当指定此标志时,不区分大小写的匹配(如果通过 CASE_INSENSITIVE 标志启用)将以与 Unicode 标准一致的方式完成。默认情况下,不区分大小写的匹配假设只匹配 US-ASCII 字符集中的字符。Unicode 意识的大小写折叠也可以通过嵌入式标志表达式 (?u) 启用。指定此标志可能会降低性能。
  • Pattern.UNIX_LINES 启用 UNIX 行模式。在此模式下,只有 \n 行终止符在 .^$ 的行为中被识别。UNIX 行模式也可以通过嵌入式标志表达式 (?d) 启用。

在以下步骤中,我们将修改测试工具 RegexTestHarness.java 以使用不区分大小写的匹配创建模式。

首先,修改代码以调用 compile 的备用版本

Pattern pattern = 
Pattern.compile(
    console.readLine("%nEnter your regex: "),
    Pattern.CASE_INSENSITIVE);

然后编译并运行测试工具以获得以下结果

Enter your regex: dog
Enter input string to search: DoGDOg
I found the text "DoG" starting at index 0 and ending at index 3.
I found the text "DOg" starting at index 3 and ending at index 6.

如您所见,字符串字面量 "dog" 匹配两个出现,无论大小写。要使用多个标志编译模式,请使用按位或运算符 | 分隔要包含的标志。为了清晰起见,以下代码示例硬编码正则表达式,而不是从控制台读取它

pattern = Pattern.compile("[az]$", Pattern.MULTILINE | Pattern.UNIX_LINES);

您也可以指定一个 int 变量

int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
Pattern pattern = Pattern.compile("aa", flags);

 

嵌入式标志表达式

也可以使用嵌入式标志表达式来启用各种标志。嵌入式标志表达式是 compile 的两个参数版本的替代方案,并在正则表达式本身中指定。以下示例使用原始测试工具 RegexTestHarness.java,其中嵌入式标志表达式 (?i) 用于启用不区分大小写的匹配。

Enter your regex: (?i)foo
Enter input string to search: FOOfooFoOfoO
I found the text "FOO" starting at index 0 and ending at index 3.
I found the text "foo" starting at index 3 and ending at index 6.
I found the text "FoO" starting at index 6 and ending at index 9.
I found the text "foO" starting at index 9 and ending at index 12.

再次,所有匹配都成功,无论大小写。

与 Pattern 的公开访问字段相对应的嵌入式标志表达式在以下表格中列出

 

常量 等效的嵌入式标志表达式
Pattern.CANON_EQ
Pattern.CASE_INSENSITIVE (?i)
Pattern.COMMENTS (?x)
Pattern.MULTILINE (?m)
Pattern.DOTALL (?s)
Pattern.LITERAL
Pattern.UNICODE_CASE (?u)
Pattern.UNIX_LINES (?d)

 

使用 Match 静态方法

Pattern 类定义了一个方便的 matches 方法,允许您快速检查给定输入字符串中是否存在模式。与所有公共静态方法一样,您应该通过其类名调用 matches,例如 Pattern.matches("\\d","1");。在此示例中,该方法返回 true,因为数字 "1" 与正则表达式 \d 匹配。

 

使用 Split 方法

split() 方法是收集位于匹配模式两侧的文本的绝佳工具。如下所示,该 split() 方法可以从字符串 "one:two:three:four:five" 中提取单词 "one two three four five"

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class SplitDemo {

    private static final String REGEX = ":";
    private static final String INPUT =
        "one:two:three:four:five";
    
    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        String[] items = p.split(INPUT);
        for(String s : items) {
            System.out.println(s);
        }
    }
}

运行此代码会产生以下结果

one
two
three
four
five

为了简单起见,您匹配了一个字符串字面量,冒号 (:),而不是一个复杂的正则表达式。由于我们仍在使用 PatternMatcher 对象,您可以使用 split() 来获取位于任何正则表达式两侧的文本。以下是一样的示例,修改为在数字处分割

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class SplitDemo2 {

    private static final String REGEX = "\\d";
    private static final String INPUT =
        "one9two4three7four1five";

    public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX);
        String[] items = p.split(INPUT);
        for(String s : items) {
            System.out.println(s);
        }
    }
}

运行此代码会产生相同的结果

one
two
three
four
five

 

其他实用程序方法

您可能还会发现以下方法有用

 

字符串中的模式方法等效项

正则表达式支持也存在于 java.lang.String 中,通过几种模拟 java.util.regex.Pattern 行为的方法。为了方便起见,下面列出了其 API 的关键摘录。

还有一个 replace() 方法,它用另一个 CharSequence 替换一个 CharSequence


上次更新: 2022 年 1 月 10 日


系列中的上一篇
当前教程
Pattern 类
系列中的下一篇

系列中的上一篇: 边界

系列中的下一篇: Matcher 类