文档

Java™ 教程-Java Tutorials 中文版
Pattern 类的方法
Trail: Essential Classes
Lesson: Regular Expressions

Pattern 类的方法

到目前为止,我们只使用测试工具以最基本的形式创建 Pattern 对象。本节探讨高级技术,例如使用标志创建模式和使用嵌入式标志表达式。它还探讨了我们尚未讨论的一些其他有用的方法。

使用 flag 创建模式

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

在以下步骤中,我们将修改测试工具 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”都匹配这两种情况。要编译带有多个标志的模式,请使用按位或运算符 "|" 分隔要包含的标志。为清楚起见,以下代码示例对正则表达式进行硬编码,而不是从 Console 中读取它:

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

你也可以指定 int 变量:

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

嵌入式标志表达式

也可以使用 embedded flag expressions (嵌入式标志表达式) 启用各种标志。嵌入式标志表达式是 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)

使用 matches(String,CharSequence) 方法

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

使用 split(String) 方法

split 方法是一个很好的工具,用于收集位于匹配模式两侧的文本。如下面 SplitDemo.java 所示,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);
        }
    }
}
OUTPUT:

one
two
three
four
five

为简单起见,我们匹配了字符串文字冒号(:)而不是复杂的正则表达式。由于我们仍在使用 PatternMatcher 对象,因此你可以使用 split 来获取位于任何正则表达式两侧的文本。这是相同的例子,SplitDemo2.java,修改为在数字上拆分:


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);
        }
    }
}
OUTPUT:

one
two
three
four
five

其他实用方法

你可能会发现以下方法也有一些用处:

java.lang.String 中的模式方法等价物

java.lang.String 中也存在正则表达式支持,它通过几种模仿 java.util.regex.Pattern 行为的方法。为方便起见,下面介绍了 API 的主要片段。

还有一个替换方法,用另一个 CharSequence 替换一个:


Previous page: Boundary Matchers
Next page: Methods of the Matcher Class