本文中,我们将演示 Pattern 更高级的特性。比如创建标记 Pattern,使用内嵌标记表达式。还会演示一些其它有用的方法。
创建标记 Pattern
Pattern 对象通过 compile 方法定义,这个方法接受一组标记,用于设置 Pattern 的匹配方式。这些标记都是位掩码,定义在 Pattern 类的静态属性中,详情可参看 Pattern API 。
下面,我们修改测试工具的代码,创建一个大小写不敏感的匹配。
首先,修改代码中的 compile 方法:
Pattern pattern =
Pattern.compile(console.readLine("%nEnter your regex: "),
Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern . compile ( console . readLine ( "%nEnter your regex: " ) , Pattern . CASE_INSENSITIVE ) ; |
运行,并测试结果:
请输入正则表达式:dog
请输入检索文本:DoGDOg
检索到匹配文本"DoG"从位置 0 到 3。
检索到匹配文本"DOg"从位置 3 到 6。
请输入正则表达式: dog 请输入检索文本: DoGDOg 检索到匹配文本 "DoG" 从位置 0 到 3 。 检索到匹配文本 "DOg" 从位置 3 到 6 。 |
从上面的例子中可以看到,dog 匹配没有区分大小写。如果要设置多个标记,可以在多个标记间添加 | (或)操作符。例如:
pattern = Pattern.compile("[az]$", Pattern.MULTILINE <b>|</b> Pattern.UNIX_LINES);
pattern = Pattern . compile ( "[az]$" , Pattern . MULTILINE < b > | < / b > Pattern .UNIX_LINES ) ; |
也可以单独指定 int 类型的变量来单独存放标记:
final int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
Pattern pattern = Pattern.compile("aa", flags);
final int flags = Pattern . CASE_INSENSITIVE | Pattern . UNICODE_CASE ; Pattern pattern = Pattern . compile ( "aa" , flags ) ; |
内嵌标记表达式
可以使用内嵌标记的正则表达式来取代两个参数的 compile 方法。下面的例子使用了原始的测试工具并且添加了 (?i) 内嵌标记来设置不区分大小写:
请输入正则表达式:(?i)foo
请输入检索文本:FOOfooFoOfoO
检索到匹配文本"FOO"从位置 0 到 3。
检索到匹配文本"foo"从位置 3 到 6。
检索到匹配文本"FoO"从位置 6 到 9。
检索到匹配文本"foO"从位置 9 到 12。
请输入正则表达式: ( ? i ) foo 请输入检索文本: FOOfooFoOfoO 检索到匹配文本 "FOO" 从位置 0 到 3 。 检索到匹配文本 "foo" 从位置 3 到 6 。 检索到匹配文本 "FoO" 从位置 6 到 9 。 检索到匹配文本 "foO" 从位置 9 到 12 。 |
可见,所有的匹配都忽略了大小写。
内嵌标记和 Pattern 的公共属性的映射关系参考下表:
静态常量 | 内嵌表达式 |
---|---|
Pattern.CANON_EQ | None |
Pattern.CASE_INSENSITIVE | (?i) |
Pattern.COMMENTS | (?x) |
Pattern.MULTILINE | (?m) |
Pattern.DOTALL | (?s) |
Pattern.LITERAL | None |
Pattern.UNICODE_CASE | (?u) |
Pattern.UNIX_LINES | (?d) |
使用 matches(String,CharSequence) 方法
Pattern 定义了静态的 matches 方法,方便用于快速地进行正则匹配。例如 Pattern.matches(“\\d”,”1″); 这段代码将会返回 true,因为 1 匹配 \d。
使用 split(String) 方法
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);
}
}
}
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
one
two
three
four
five
|
为了简单,我们使用冒号来取代复杂的正则表达式。当然,我们也可以用任意正则表达式来执行这个方法:
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);
}
}
}
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
one
two
three
four
five
|
其它有用的方法
public static String quote(String s)
:返回匹配字符串 s 的字符串字面量正则表达式。这个方法将返回 String 类型,可用于创建 Pattern 并且匹配字符串 s。参数中的元数据或转义字符并没有特殊的含义。
public String toString()
:返回当前 Pattern 的正则表达式。
String 和 Pattern 中等效的方法
正则表达式在 java.lang.String 中也很常见,有几个方法的行为和 Pattern 中的方法一致,主要摘录如下:
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) :str.split(regex) 等效于 Pattern.compile(regex).split(str, 0)。