Pattern正则表达式的编译表示形式。
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式
first,将根据非捕获组和捕获组进行分类来展示正则表达式的一些常规的规则:
/**
* 非捕获类型
* x 字符 x
* \\ 反斜线字符
* [abc] a、b 或 c(简单类)
* [^abc] 任何字符,除了 a、b 或 c(否定)
* [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
* [a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
* [a-z&&[def]] d、e 或 f(交集)
* . 任何字符(与行结束符可能匹配也可能不匹配)
* \d 数字:[0-9]
* \D 非数字: [^0-9]
* \s 空白字符:[ \t\n\x0B\f\r]
* \S 非空白字符:[^\s]
* \w 单词字符:[a-zA-Z_0-9]
* \W 非单词字符:[^\w]
* \b 单词边界
* ^ 行的开头
* $ 行的结尾
* X? X,一次或一次也没有
* X* X,零次或多次
* X+ X,一次或多次
* X{n} X,恰好 n 次
* X{n,} X,至少 n 次
* X{n,m} X,至少 n 次,但是不超过 m 次
*/
/**
* 捕获类型
* (X) X,作为捕获组
* \n 任何匹配的 nth 捕获组
* 注意:
* 1、有的方法需要传多个参数,当第二个参数需要用第一个参数的组是直接写相应的标号并在前面加上$,例如引入第一组"$1"
* 2、多级符合的捕获组排序规则
* 如:在表达式 ((A)(B(C))) 组序号就根据从左往右看左括号
* 1、((A)(B(C)))
* 2、(A)
* 3、(B(C))
* 4、(C)
* so,对于零组表示是对于所有非捕获表达式都作为0组
*/
正则表达式的应用主要是在字符串中,所以根据字符串的方法来分析:
匹配:
boolean | matches(String regex) |
String[] | split(String regex) |
String | replaceAll(String regex, String replacement) |
static Pattern | compile(String regex) |
1、匹配:
//场景: 要求不能以0开头,必须是数字,长度在5-20位
String str = "0543543543";
String reg = "[1-9][0-9]{4,19}";
boolean result = str.matches(reg);
System.out.println(result);
2、
分割:
//场景:将23 19 -1 9 56这串数字按照空格进行分割
String str = "23 19 -1 9 56";
String reg = " {1,}";//和" +"等价的
String[] result = str.split(reg);
for(String s : result){
System.out.println(s);
}
3、替换:
//场景:将手机号码中间四位变成****
String str = "13432432333";
String reg = "(\\d{3})\\d{4}(\\d{4})";
String result = str.replaceAll(reg, "$1****$2");
System.out.println(result);
//场景:werqqtyuzzzio 将连续重复的变成单个单词 将qq用q zzz用z替换
<span style="font-size:12px;">String str = "werqqtyuzzzio";
String reg = "(.)\\1+";
// (.)将任何字符变成一个组 \\1表示第一个组 后面加上+表示>=1
String result = str.replaceAll(reg, "$1");//
//对于另一个参数引用前一个参数的组需要在前面加上标识符
System.out.println(result);</span>
4、获取:
//场景:"da jw zhu yi le,yao pai wei dian ying le!" 把三个字母的单词取出来
String str = "da jw zhu yi le,yao pai wei dian ying le!";
String reg = "\\b[a-z]{3}\\b";//把三个字母组成的单词都取出来
//正则规则被编译成Pattern对象
Pattern p = Pattern.compile(reg);
//通过正则对象的方法matcher和字符串想关联获取匹配器对象
Matcher m = p.matcher(str);
//使用匹配器的方法对字符串进行操作
while(m.find()){
m.group();//取出子序列
}
//注意上面要加上\\b表示单词的边界
//m.start()表示找到第一个字母的索引 m.end()表示找到字符串后一个字母的索引
}
综合应用:
//场景:我我我...我我...我要..要要..要要..学.学...学学...编程 变成 我要学编程
String str = "我我我...我我...我要..要要..要要..学.学...学学...编程";
//先去掉. 然后在替换重复的
String reg = "\\.+";
String result1 = str.replaceAll(reg, "");//将.都用空字符串替换
System.out.println(result1);
String reg1 = "(.)\\1+";
String result2 = result1.replaceAll(reg1, "$1");//将重复的去掉
System.out.println(result2);
//场景:192.108.90.34 10.10.10.10 5.5.5.5 30.107.100.5 对ip地址字符串中的ip地址进行排序,按照ip的分类顺序
<span style="font-size:12px;">// 为了排序方便。最好让ip中的每一段都是三位,这样就可以用字典顺序进行排序了。
//
// 1、给每一段进行补零的操作
// 2、而每一段需要的补的零又不一样多,咋办?
// 3、干脆,都按最多的两个零补
// 4、然后在每一段保留最后三位
String ip = "192.108.90.34 10.10.10.10 5.5.5.5 30.107.100.5";
ip = ip.replaceAll("(\\d+)","00$1");
System.out.println(ip);
ip = ip.replaceAll("0*(\\d{3})","$1");
System.out.println(ip);
String[] ips = ip.split(" +");
Arrays.sort(ips);
for(String i : ips){
System.out.println(i.replaceAll("0*(\\d+)","$1"));
}</span>
//场景:获取某个网址上的QQ邮箱地址
/**
* 利用正则表达式爬虫获取网络的邮箱
*/
try {
URL url = new URL("http://tieba.baidu.com/p/3878991406");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String line = null;
while ((line = br.readLine()) != null) {
Pattern p = Pattern.compile("\\w+@\\w+\\.\\w+");
Matcher m = p.matcher(line);
if (m != null) {
while(m.find()){
System.out.println(m.group());
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}