正则表达式小结

来源:互联网 发布:torrent下载软件 编辑:程序博客网 时间:2024/06/06 08:33

学习网址:http://www.w3cschool.cc/java/java-regular-expressions.html

实现目的:每四个数加个空格,数的长度不定。

例子:参考:http://biancheng.dnbcw.info/java/110082.html

String num1 = "1234562222";System.out.println("1234562222".replaceAll("\\d{4}(?!$)", "$0 "));//这句就够了//String res = Pattern.compile("\\d{4}(?!$)").matcher(num1).replaceAll("$0 ");//System.out.println(res);  例子中$0代表匹配的表达式。结果:1234 5622 22

下面是学习期间的一些理解和总结:

(pattern)

匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"\("或者"\)"。

注:在正则表达式中,被小括号括起来的子表达式称为捕获组,正则表达式在求值期间将保存匹配这些捕获组表达式的输入子序列。一旦完全匹配操作完成,这些保存的代码片断可通过确定相应的组号从 Matcher对象上重新获取。捕获组可以嵌套使用,数量可以通过从左到右计算左括弧(开括号)得到。无论整个表达式是否有子组,它的捕获组总能记为组零(group zero)。

例如,正则表达式 A((B)(C(D)))可能有的捕获组编号如下所示:

组号    表达式组 
0   A((B)(C(D))) 
1   ((B)(C(D))) 
2    (B) 
3   (C(D)) 
4   (D)

参照下例子理解捕获组

String num = "dog cast dogg";String pattern = "d(o)?(gg?)";Pattern r = Pattern.compile(pattern);Matcher m = r.matcher(num);int count=m.groupCount();System.out.println("group个数:"+count);if(m.find()){System.out.println("group 0: " + m.group(0));System.out.println("group 1: " + m.group(1));System.out.println("group 2: " + m.group(2));}//结果如下:可看出来:()个数就是组个数 而group 0是个特殊的组,它总是代表整个表达式。该组不包括在groupCount的返回值中。//group个数:2//group 0: dog//group 1: o//group 2: g

(?=pattern)

执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。

(?!pattern)

执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 可理解为 不消耗任何字符,如下例。


细节:(?=exp) 也叫零宽度正预测先行断言

它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

  (?!exp) 也叫零宽度负向预测先行断言

\b\w*q[^u]\w*\b 匹配包含后面不是字母u的字母q的单词。

可是你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。

然而:
负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b

参考:http://www.cnblogs.com/mu-mu/archive/2013/02/06/2893581.html

注释:(零宽度正预测先行断言)仅当子表达式在此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。

最后一个小例子自己在这犯错了,所以记录一下:

import java.util.regex.Matcher;import java.util.regex.Pattern;public class Test {public static void main(String[] args) {String s = "<BODY>" + "<H1>Welcome to my Homepage</H1>"+ "Content is divided into two sections:<BR>"+ "<H2>ColdFusion</H2>"+ "Information about Macromedia ColdFusion."+ "<H2>Wireless</H3>"+ "Information about Bluetooth, 802.11, and more." + "</BODY>";String reg = "<[hH]([1-6])>.*</[hH]\\1>";Pattern patt = Pattern.compile(reg);Matcher mc = patt.matcher(s);System.out.println(s.replaceAll(reg, ",$0+++"));while (mc.find()) {System.out.println(mc.group().trim());}System.out.println("------------------------------");/** * 输出: <H1>Welcome to my Homepage</H1> <H2>ColdFusion</H2> */String ss="ABCDEFGHIJKL";String reg1 = "\\S{4}(?!$)";Pattern patt1 = Pattern.compile(reg1);Matcher mc1 = patt1.matcher(ss);while (mc1.find()) {System.out.println("Found value: " + mc1.group(0));System.out.println(mc1.group().trim());}System.out.println("------------------------------");String pattern1 = "\\d{4}(?!$)";String num1 = "1234567890";Pattern r1 = Pattern.compile(pattern1);Matcher m1 = r1.matcher(num1);StringBuilder res=new StringBuilder();/** * 写成if了,还一直纳闷怎么就匹配不出来 */while (m1.find()) {System.out.println("Found value: " + m1.group(0));res.append(m1.group(0)+",");System.out.println(m1.group().trim());}System.out.println(res);/** * 输出结果如下: * Found value: ABCD *ABCD *Found value: EFGH *EFGH *Found value: 1234 *1234 *Found value: 5678 *5678 *  1234,5678, */}}


0 0
原创粉丝点击