学习网址: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,
*/
}
}