正则表达式 RegularExpressions
if 忘记了 please 看一下
1 import java.util.regex.Matcher; 2 import java.util.regex.Pattern; 3 import org.junit.Test; 4 5 /** 6 * Regular Expressions 7 * Test jdk 1.7.0_80 64Bit 8 */ 9 public class RegExp { 10 11 @Test // Pattern,Matcher 12 public void test1(){ 13 p("abc".matches("...") );//true 14 p("a3323d".replaceAll("\\d", "-") ); //a----d 15 p("a3323d".replaceFirst("\\d", "-") ); //a-323d 16 17 //a-z 的字母,恰好出现3次 18 Pattern p = Pattern.compile("[a-z]{3}"); //先编译模式,以后匹配速度会快;现场编译的话,速度没那么快 19 Matcher m = p.matcher("dce"); //匹配后的结果存放在Matcher中,Matcher叫做匹配器 20 p( m.matches() ); //true, matches()表示是否匹配整个字符串 21 22 "dec".matches("[a-z]{3}"); //3句话的效率比这一句话的效率高 23 p("decd".matches("[a-z]{3,}") );//true,至少3次 24 p("decd".matches("[a-z]{3,4}") );//true,至少3次,不超过4次,即:{}包含两端3到4次 25 p("decd5".matches("[a-z]{3,4}") );//false,至少3次,不超过4次 26 p("23423435435".matches("\\d{3,100}") ); //true 27 } 28 29 @Test //. * + ?, 英文叫做meta character, 30 public void test2(){ 31 p("a".matches(".") );//1个任意字符(不匹配换行符 \r\n) 32 p("\n".matches(".")); //false 33 p("\r".matches(".")); //false 34 p("\r\n".matches(".."));//false 35 p("\r\n".matches("\r\n")); //true 36 37 Pattern p = Pattern.compile("..", Pattern.DOTALL); //让 . 匹配所有字符 38 p.matcher("\r\n").matches(); //true 39 40 p("--------------*"); 41 p("aa".matches("aa") ); 42 p("aa".matches("aa*") );//true,0次或者多次, 只是针对单个字符a, aa*:第二个a出现0次或多次 43 p("aa".matches("a*") );//true,这里是1次 44 p("aa".matches("aaa*") );//true,这里是0次 45 p("aa".matches("aaaa*") );//false 46 p("".matches("a*")); //true 47 48 p("-------------+"); 49 p("aaaa".matches("a+") );//true, 1次或者多次 50 p("aa".matches("a+") );//true 51 p("aa".matches("aa+") );//true, aa+:第二个a出现1次或多次 52 p("aa".matches("aaa+") );//false 53 // p("aa".matches("+") ); //编译会错误 54 p("abcd".matches(".+") );//ture 55 56 p("-------------?"); 57 p("a".matches("a?") );//ture,0个or 1个 58 p("".matches("a?") );//ture 59 p("ab".matches("a?") );//false 60 p("aaaa".matches("a?") );//false, 2007年尚学堂一版jdk,这里是ture,应该是bug 61 p("ab".matches("a.?") );//true, a.? a然后是任意0个或1个 62 63 p("-------------[]"); 64 p("192.168.80.201".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}") ); //true 65 p("192.168.80.201".matches("\\d{1,3} \\. \\d{1,3}\\.\\d{1,3}\\.\\d{1,3}") ); //false 不能空格,空格也是位置:\s 66 p("299".matches("[1-2][0-9][0-9]"));//true 包含前后边界 67 p("100".matches("[1-2][0-9][0-9]"));//true 68 } 69 70 @Test //范围 []中匹配的是一个字符 71 public void test3(){ 72 p("a".matches("[abc]")); // [abc] 代表中挂号的某一个字母,匹配的是一个字符,而不是abc全部 73 p("c".matches("[^abc]")); //false []中的^ 表示除了abc 其他字母都可以 74 p("d".matches("[^abc]")); // true 75 p("de".matches("[^abc]")); // false 76 p("dA".matches("[^abc][a-zA-Z]")); // true 77 p("dA".matches("[^abc]([a-z]|[A-Z])") ); // true, 等价于上面的写法,用了() 和 | 78 p("dA".matches("[^abc][a-z[A-Z]]") ); // true, 等价于上面的写法 79 p("R".matches("[A-Z&&[RPC]]") ); // true 80 } 81 82 @Test // \s \w \S \W \d \D 83 public void test4(){ 84 p(" \n\r\t".matches("\\s{4}")); //true 85 p(" ".matches("\\S")); //false 86 p("".matches("\\S")); //false 87 p("a_0".matches("\\w{3}")); 88 p("abc999&^#%".matches("[a-z]{1,3}\\d+[&^#%]+") ); 89 // p("\\".matches("\\")); //运行报错, 前面"\\" 是1个 \,java中匹配一个\,需要\\\\,需要仔细体会下 90 p("\\".matches("\\\\")); 91 } 92 93 @Test //边界 94 public void test5(){ 95 p("hello sir".matches("^he.*") ); //true. ^在[]里边代表取反,在外边表示 开头 96 p("hello sir".matches(".*r$") ); //true 97 p("hello sir".matches("^h[a-z]{1,3}o\\b.*") ); //true 98 p("hell osir".matches("^h[a-z]{1,3}\\bo.*") ); //false 99 p("hell osir".matches("^h[a-z]{1,3}\\b\\s+o.*") ); //true, \b单词边界仅仅表示边界,并不占位,仍然需要加\s 100 101 p("----------white line"); 102 p(" \r\n".matches("^\\s*$")); 103 p(" \r\n".matches("^[\\s&&[^\\n]]*\\n$")); //开头是空白字符,但不是换行符 104 p("\r\n".matches("^[\\s&&[^\\n]]*[\\n|\\r]$")); 105 p("\r".matches("^[\\s&&[^\\n]]*[\\n|\\r]$")); 106 p("\n".matches("^[\\s&&[^\\n]]*[\\n|\\r]$")); //通常做匹配都是$BufferReader.readLine 这里读出来的行,这里的行是不包含终止符的 107 108 p("------------------\\b"); 109 p("aaa 8888c".matches(".*\\d{4}.")); //true 110 p("aaa 8888c".matches(".*\\b\\d{4}.")); //true 111 p("aaa 8888c".matches(".*\\b\\s\\d{4}.")); //true 112 p("aaa 8888c".matches(".*\\s\\b\\d{4}.")); //true 113 p("aaa 8888c".matches("a{3}\\b\\d{4}.")); //这里就是false,需要\s 114 p("aaa 8888c".matches("a{3}\\b\\s\\d{4}.")); //true 115 p("aaa 8888c".matches("a{3}\\b.\\d{4}.")); //true 116 p("aaa 8888c".matches("a{3}.\\b\\d{4}.")); //true 117 118 p("---------------email"); 119 p("ali.google@gmail.com".matches("[\\w[.-]]+@\\w+\\.\\w+")); // .在[]中就表示字符,不需要转义 120 p("ali.google@gmail.com".matches("[\\w[\\.-]]+@\\w+\\.\\w+")); // 加上也是正确的 121 p("ali.google@gmail.com".matches("[\\w[\\.-]]+@[\\w[\\.-]]+\\.\\w{2,4}")); 122 p("ali.google@gmail.com".matches("[\\w[\\.-]]+@[\\w[\\.-]]+\\.(cc|com|net|cn|so)$")); 123 } 124 125 @Test //matcher 126 public void test6(){ 127 Pattern p = Pattern.compile("\\d{3,5}"); 128 String s = "123-23432-789-98"; 129 Matcher m = p.matcher(s); 130 p(m.matches() ); //cursor走到第4个位置时,发现已经不匹配,返回结果,cursor依然停在第4个位置,重新find()子串时需要reset 131 m.reset(); 132 p(m.find() ); 133 p(m.start()+" - "+m.end() );//获取位置 134 p(m.find() ); 135 p(m.start()+" - "+m.end() ); 136 p(m.find() ); 137 p(m.start()+" - "+m.end() ); 138 p(m.find() ); 139 } 140 141 @Test //Pattern 编译时忽略大小写 & replace 142 public void test7(){ 143 // Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE); 144 Pattern p = Pattern.compile("(?i)java"); //与上面的等价 (?i)是non-caputuring的表示方式 145 146 Matcher m = p.matcher("java iLoveJaVa JAVaa he hate JAVA cef"); 147 while(m.find() ){ 148 p( m.group() ); 149 } 150 /* output: 151 java 152 JaVa 153 JAVa 154 JAVA */ 155 156 p(m.replaceAll("PYTHON") ); //PYTHON iLovePYTHON PYTHONa he hate PYTHON cef 157 158 //单数替换成PYTHON,双数替换成python 159 m.reset(); 160 StringBuffer buf = new StringBuffer(); 161 int i=0; 162 while(m.find() ){ 163 i++; 164 if(i%2==0){ 165 m.appendReplacement(buf, "python"); 166 }else{ 167 m.appendReplacement(buf, "PYTHON"); 168 } 169 } 170 m.appendTail(buf); 171 p(buf); //PYTHON iLovepython PYTHONa he hate python cef 172 } 173 174 @Test // group 175 public void test8(){ 176 Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})"); 177 String s = "123ab-23432cd-789er-98s"; 178 Matcher m = p.matcher(s); 179 while(m.find() ){ 180 p(m.group(1) ); //分组怎么看,整个一组是0, m.group(0) == m.group(); 从左边看第1个( 就是第1组,第2个就是第二组 181 /* 123 182 23432 183 789 */ 184 } 185 } 186 187 @Test //quantifiers 188 public void test9(){ 189 //默认: greedy quantifier 一口吞10个,一看不符合然后慢慢吐 190 /* Pattern p = Pattern.compile("(.{3,10})[0-9]"); 191 String s = "aaaa8bbbb9"; 192 Matcher m = p.matcher(s); 193 while(m.find() ){ 194 p( m.group(0) ); 195 }*/ 196 197 //Reluctant quantifier 不情愿的,懒懒的,吃最少的,先吃3个看看符不符合,不行再吃 198 Pattern p = Pattern.compile("(.{3,10}?)[0-9]"); 199 String s = "aaaa8bbbb9"; 200 Matcher m = p.matcher(s); 201 while(m.find() ){ 202 p( m.group() ); 203 } 204 } 205 206 @Test //non-capturing group, 207 public void test10(){ 208 /* Pattern p = Pattern.compile(".{3}(?=a)"); //以a结尾,但是不捕获, Perl程序员喜欢这么搞,需要读懂,有替代方案 209 String s = "9x7za8bbbb9"; 210 Matcher m = p.matcher(s); 211 while(m.find() ){ 212 p( m.group() ); //output: x7z 213 }*/ 214 215 Pattern p = Pattern.compile("(?=a).{3}"); // lookahead , 放在前面包含a 216 String s = "9x7za8bbbb9"; 217 Matcher m = p.matcher(s); 218 while(m.find() ){ 219 p( m.group() ); //output: a8b 220 } 221 } 222 223 @Test //引用 224 public void test11(){ 225 Pattern p = Pattern.compile("(\\d\\d)\\1"); //向前引用 \1 表示 现在的位置必须和前面的一样 226 String s = "1212"; 227 Matcher m = p.matcher(s); 228 p(m.matches() ); //true 229 230 p("122".matches("(\\d(\\d))\\2") ); //true \2表示第2组 231 p("134".matches("(\\d(\\d))\\2") ); //false \2表示第2组和当前位置的“内容”完全一样,而不仅仅指类型一样 232 233 } 234 235 public static void p(Object o){ 236 System.out.println(o); 237 } 238 239 }