11. Matcher 类的方法
下面列出的方法是按照功能来分组的。
索引方法
索引方法(index methods)提供了一些正好在输入字符串中发现匹配的索引值:
public int start() : 范围之前匹配的开始索引
public int start(int group) : 返回之前匹配操作中通过给定组所捕获序列的开始索引
public int end() : 返回最后匹配字符串后的偏移量
public int end(int group) :返回之前匹配操作中给定组所捕获序列的最后字符之后的偏移量
研究方法
研究方法(study methods)回顾输入的字符串,并且返回一个用于指示是否找到模式的布尔值
public boolean lookingAt() :尝试从区域开始处开始,输入序列与该模式匹配。
public boolean find() : 尝试地寻找输入序列中,匹配模式的下一个子序列。
public boolean find(int start) : 重置匹配器,然后从指定的索引处开始,尝试地寻找输入序列中,匹配模式的下一个子序列。
public boolean matches() : 尝试将整个区域与模式进行匹配
替换模式
替换模式(replacement)用于在输入的字符串中替换文本有用处的方法。
public Matcher appendReplacement(StringBuffer sb,String replacement) : 实现非结尾处的增加和替换操作。
public StringBuffer appendTail(StringBuffer sb) : 实现结尾处的增加和替换操作。
public String replaceAll(String replacement) : 使用给定的替换字符串来替换输入序列中匹配模式的每一个子序列。
public String replaceFirst(String replacement) : 使用指定的替换字符串来替换输入序列中匹配模式的第一个子序列。
public static String quoteReplacement(String s) : 返回指定字符串的字面值来替换字符串。这个方法会生成一个字符串,用作Matcher的appendReplacement方法中的字面值替换s。所产生的字符串与作为字面值序列的s中字符序列匹配。斜线(\)和美元符号($)将不再有特殊意义了。
11.1 使用start和end方法
实例程序MatcherDemo.java 用于计算输入序列中单词"dog"的出现次数。
package com.fortune.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-29 * Time: 下午5:38 */ public class MatcherDemo { private static final String REGEX = "\\bdog\\b"; private static final String INPUT = "dog dog dog doggie dogg"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // 获得匹配器对象 int count = 0; while (m.find()) { count++; System.out.println("Match number " + count); System.out.println("start(): " + m.start()); System.out.println("end(): " + m.end()); } } }
输出:
Match number 1 start(): 0 end(): 3 Match number 2 start(): 4 end(): 7 Match number 3 start(): 8 end(): 11
可以看出,这个例子使用了单词边界,用于确保更长单词中的字母"d" "o" "g" 就不是字符串了。 它也输出了一些有用的信息,在输入的字符串中什么地方有匹配。start方法返回在以前的匹配操作期间,由给定组所捕获子序列的开始处索引,end方法返回匹配到最后一个字符索引加1。
11.2 使用matches和lookAt方法
matches 和 lookingAt方法都是尝试该模式匹配输入序列。然而不同的是,matches要求匹配整个输入字符串,而lookingAt 不是这样。这两个方法都是从输入字符串的开头开始的。下面是MatchsLooking.java 完整的代码:
package com.fortune.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-29 * Time: 下午6:31 */ public class MatchesLooking { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static Pattern pattern; private static Matcher matcher; public static void main(String args[]) { pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); System.out.println("Current REGEX is :" + REGEX); System.out.println("Current INPUT is :" + INPUT); System.out.println("lookingAt():" + matcher.lookingAt()); System.out.println("matches():" + matcher.matches()); } }
输出:
Current REGEX is :foo Current INPUT is :fooooooooooooooooo lookingAt():true matches():false
11.3 使用replaceFirst(String) 和 replaceAll(String) 方法
replaceFirst 和 replaceAll 方法替换匹配给定正则表达式的文本。从它们的名字可以看出,replaceFirst替换第一个匹配到的,而replaceAll替换所有匹配的,下面是ReplaceDemo.java的代码:
package com.fortune.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-29 * Time: 下午6:40 */ public class ReplaceDemo { private static String REGEX = "dog"; private static String INPUT = "The dog says meow.All dogs say meow."; private static String REPLACE = "cat"; public static void main(String args[]) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.print(INPUT); } }
输出:
The cat says meow.All cats say meow.
在上面的例子中,所有的dog都被替换成了cat.但是为什么在这里停下来了呢? 你可以替换匹配任何正则表达式文本,这样由于替换一个简单的像dog一样的文字。这个方法的API描述了"给定正则表达式a*b",在输入"aabfooaabfooabfoob" 和替换的字符串是"-"情况下,表达式的匹配器调用方法后,会产生字符串"-foo-foo-foo-".
下面是ReplaceDemo2.java 的代码:
package com.fortune.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-29 * Time: 下午6:40 */ public class ReplaceDemo2 { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String args[]) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.print(INPUT); } }
输出:
-foo-foo-foo-
仅要替换模式一次时,可以简单地调用replaceFirst 用于取代replaceAll,它接受同样的参数。
11.4 使用appendReplacement(StringBuffer,String) 和appendTail(StringBuffer) 方法
Matcher类也提供了appendReplacement 和 appendTail 两个方法用于文本替换.下面这个例子(RegexDemo.java)使用了这两个方法完成与replaceAll 相同的功能。
package com.fortune.test; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-29 * Time: 下午6:57 */ public class RegexDemo { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, REPLACE); } m.appendTail(sb); System.out.println(sb.toString()); } }
输出:
-foo-foo-foo-
11.5 在java.lang.String 中等价的Matcher方法
为了使用方便,String类看上去还不错地模仿了Matcher的两个方法:
public String replaceFirst(String regex,String replacement) :使用给定的替换字符串替换该字符串中匹配了给定正则表达式的第一个子字符串。调用 str.replaceFirst(regex, repl)方法与使用Pattern.compile(regex).matcher(str).replaceFirst(repl)产生的结果是完全相同的。
public String replaceAll(String regex, String replacement):使用给定的替换字符串替换该字符串中匹配了给定正则表达式的每一个子字符串。调用 str.replaceAll(regex, repl)方法与使用 Pattern.compile(regex).matcher(str).replaceAll(repl)产生的结果是完全相同的。