Java教程是针对JDK 8编写的。本页面描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及其后续版本中更新的语言功能的概述。
请参阅JDK发布说明,了解所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
到目前为止,我们只使用测试工具创建了最基本形式的Pattern
对象。本节将探讨一些高级技术,例如使用标志创建模式和使用嵌入式标志表达式。还将探讨一些我们尚未讨论的其他有用方法。
Pattern
类定义了一个可接受一组影响模式匹配方式的标志的替代compile
方法。标志参数是一个位掩码,可以包括以下任何公共静态字段:
Pattern.CANON_EQ
启用规范等价。当指定了此标志时,只有当两个字符的完全规范分解匹配时,它们才被视为匹配。例如,当指定了此标志时,表达式"a\u030A"
将与字符串"\u00E5"
匹配。默认情况下,匹配不考虑规范等价。指定此标志可能会导致性能损失。Pattern.CASE_INSENSITIVE
启用不区分大小写的匹配。默认情况下,不区分大小写的匹配假定仅匹配美国ASCII字符集中的字符。通过与此标志结合使用UNICODE_CASE标志可以启用支持Unicode的不区分大小写匹配。也可以通过嵌入的标志表达式(?i)
来启用不区分大小写的匹配。指定此标志可能会稍微降低性能。Pattern.COMMENTS
允许在模式中使用空格和注释。在此模式下,忽略空格,并且以#
开头的嵌入式注释将被忽略直到行末。也可以通过嵌入的标志表达式(?x)
来启用注释模式。Pattern.DOTALL
启用dotall模式。在dotall模式下,表达式.
匹配任何字符,包括行终止符。默认情况下,此表达式不匹配行终止符。也可以通过嵌入的标志表达式(?s)
来启用dotall模式。(s是Perl中的"single-line"模式的助记符)Pattern.LITERAL
启用模式的字面解析。当指定了此标志时,指定模式的输入字符串将被视为字面字符序列。输入序列中的元字符或转义序列将不会被特殊处理。标志CASE_INSENSITIVE
和UNICODE_CASE
在与此标志结合使用时仍会影响匹配。其他标志变得多余。没有用于启用字面解析的嵌入标志字符。Pattern.MULTILINE
启用多行模式。在多行模式下,表达式^
和$
分别匹配行终止符之后或之前的位置,或者匹配输入序列的结尾。默认情况下,这些表达式仅匹配整个输入序列的开头和结尾。也可以通过嵌入的标志表达式(?m)
来启用多行模式。Pattern.UNICODE_CASE
启用Unicode感知大小写折叠。当指定了此标志时,大小写不敏感匹配(由CASE_INSENSITIVE
标志启用)将与Unicode标准一致。默认情况下,大小写不敏感匹配假定只匹配US-ASCII字符集中的字符。可以通过嵌入的标志表达式(?u)
来启用Unicode感知大小写折叠。指定此标志可能会导致性能下降。Pattern.UNIX_LINES
启用UNIX行模式。在此模式下,'\n'
被识别为.
、^
和$
的行终止符。可以通过嵌入的标志表达式(?d)
来启用UNIX行模式。RegexTestHarness.java
compile
Pattern pattern = Pattern.compile(console.readLine("%n输入正则表达式: "), Pattern.CASE_INSENSITIVE);
输入正则表达式: dog 输入要搜索的字符串: DoGDOg 我在索引0到索引3之间找到文本 "DoG"。 我在索引3到索引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);
compile
(?i)
输入正则表达式: (?i)foo 输入要搜索的字符串: FOOfooFoOfoO 我在索引0到索引3之间找到文本 "FOO"。 我在索引3到索引6之间找到文本 "foo"。 我在索引6到索引9之间找到文本 "FoO"。 我在索引9到索引12之间找到文本 "foO"。
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); } } }
输出: one two three four five
为了简单起见,我们匹配了一个字符串字面量,即冒号(:
),而不是一个复杂的正则表达式。由于我们仍然使用Pattern
和Matcher
对象,您可以使用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); } } }
输出: one two three four five
您可能也会发现以下方法有一些用处:
public static String quote(String s)
:返回指定字符串的字面模式String
。该方法生成一个String
,可用于创建一个Pattern
,该Pattern
将匹配String s
,就好像它是一个字面模式。输入序列中的元字符或转义序列将不被赋予特殊含义。public String toString()
:返回此模式的String
表示形式。这是编译此模式的正则表达式。java.lang.String
中的Pattern方法等效方法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"。