使用标志创建模式
该 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_INSENSITIVE 和 Pattern.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
为了简单起见,您匹配了一个字符串字面量,冒号 (:),而不是一个复杂的正则表达式。由于我们仍在使用 Pattern 和 Matcher 对象,您可以使用 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
其他实用程序方法
您可能还会发现以下方法有用
public static String quote(String s) 为指定的 String 返回一个字面模式 String。此方法生成一个 String,该字符串可用于创建 Pattern,该模式将匹配 String s,就好像它是字面模式一样。输入序列中的元字符或转义序列将不会被赋予任何特殊含义。
public String toString() 返回此模式的 String 表示形式。这是编译此模式的正则表达式。
字符串中的模式方法等效项
正则表达式支持也存在于 java.lang.String 中,通过几种模拟 java.util.regex.Pattern 行为的方法。为了方便起见,下面列出了其 API 的关键摘录。
public boolean matches(String regex): 判断此字符串是否与给定的正则表达式匹配。以 str.matches(regex) 形式调用此方法的结果与表达式 Pattern.matches(regex, str) 的结果完全相同。
public String[] split(String regex, int limit): 根据给定正则表达式的匹配项拆分此字符串。以 str.split(regex, n) 形式调用此方法的结果与表达式 Pattern.compile(regex).split(str, n) 的结果相同。
public String[] split(String regex): 根据给定正则表达式的匹配项拆分此字符串。此方法的工作方式与使用给定表达式和限制参数为零调用双参数 split 方法相同。尾随空字符串不包含在结果数组中。
还有一个 replace() 方法,它用另一个 CharSequence 替换一个 CharSequence
public String replace(CharSequence target,CharSequence replacement): 用指定的文字替换序列替换此字符串中与文字目标序列匹配的每个子字符串。替换从字符串的开头到结尾进行,例如,在字符串 "aaa" 中用 "b" 替换 "aa" 将导致 "ba" 而不是 "ab"。