java.util.regex.*; com.bruceeckel.simpletest.*; java.util.*; SplitDemo { Test monitor = Test(); main(String[] args) { String input = ; System.out.println(Arrays.asList( Pattern.compile().split(input))); System.out.println(Arrays.asList( Pattern.compile().split(input, 3))); System.out.println(Arrays.asList( .split())); monitor.expect( String[] { , , }); } }
第二个split( )会限定分割的次数。
正则表达式是如此重要,以至于有些功能被加进了String类,其中包括split( )(已经看到了),matches( ),replaceFirst( )以及replaceAll( )。这些方法的功能同Pattern和Matcher的相同。
替换操作
正则表达式在替换文本方面特别在行。下面就是一些方法:
replaceFirst(String replacement)将字符串里,第一个与模式相匹配的子串替换成replacement。
replaceAll(String replacement),将输入字符串里所有与模式相匹配的子串全部替换成replacement。
appendReplacement(StringBuffer sbuf, String replacement)对sbuf进行逐次替换,而不是像replaceFirst( )或replaceAll( )那样,只替换第一个或全部子串。这是个非常重要的方法,因为它可以调用方法来生成replacement(replaceFirst( )和replaceAll( )只允许用固定的字符串来充当replacement)。有了这个方法,你就可以编程区分group,从而实现更强大的替换功能。
调用完appendReplacement( )之后,为了把剩余的字符串拷贝回去,必须调用appendTail(StringBuffer sbuf, String replacement)。
下面我们来演示一下怎样使用这些替换方法。说明一下,这段程序所处理的字符串是它自己开头部分的注释,是用正则表达式提取出来并加以处理之后再传给替换方法的。
java.util.regex.*; java.io.*; com.bruceeckel.util.*; com.bruceeckel.simpletest.*; TheReplacements { Test monitor = Test(); main(String[] args) Exception { String s = TextFile.read(); Matcher mInput = Pattern.compile(, Pattern.DOTALL) .matcher(s); (mInput.find()) s = mInput.group(1); s = s.replaceAll(, ); s = s.replaceAll(, ); System.out.println(s); s = s.replaceFirst(, ); StringBuffer sbuf = StringBuffer(); Pattern p = Pattern.compile(); Matcher m = p.matcher(s); (m.find()) m.appendReplacement(sbuf, m.group().toUpperCase()); m.appendTail(sbuf); System.out.println(sbuf); monitor.expect( String[]{ , , , , , , , , , }); } }
用TextFile.read( )方法来打开和读取文件。mInput的功能是匹配'/*!' 和 '!*/' 之间的文本(注意一下分组用的括号)。接下来,我们将所有两个以上的连续空格全都替换成一个,并且将各行开头的空格全都去掉(为了让这个正则表达式能对所有的行,而不仅仅是第一行起作用,必须启用多行模式)。这两个操作都用了String的replaceAll( )(这里用它更方便)。注意,由于每个替换只做一次,因此除了预编译Pattern之外,程序没有额外的开销。
replaceFirst( )只替换第一个子串。此外,replaceFirst( )和replaceAll( )只能用常量(literal)来替换,所以如果每次替换的时候还要进行一些操作的话,它们是无能为力的。碰到这种情况,得用appendReplacement( ),它能在进行替换的时候想写多少代码就写多少。在上面那段程序里,创建sbuf的过程就是选group做处理,也就是用正则表达式把元音字母找出来,然后换成大写的过程。通常你得在完成全部的替换之后才调用appendTail( ),但是如果要模仿replaceFirst( )(或"replace n")的效果,你也可以只替换一次就调用appendTail( )。它会把剩下的东西全都放进sbuf。
你还可以在appendReplacement( )的replacement参数里用"$g"引用已捕获的group,其中'g' 表示group的号码。不过这是为一些比较简单的操作准备的,因而其效果无法与上述程序相比。
reset( )
此外,还可以用reset( )方法给现有的Matcher对象配上个新的CharSequence。
java.util.regex.*; java.io.*; com.bruceeckel.simpletest.*; Resetting { Test monitor = Test(); main(String[] args) Exception { Matcher m = Pattern.compile() .matcher(); (m.find()) System.out.println(m.group()); m.reset(); (m.find()) System.out.println(m.group()); monitor.expect( String[]{ , , , , , }); } }
如果不给参数,reset( )会把Matcher设到当前字符串的开始处。
如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语,那么“正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜索匹配字符串的模式。