10 Java SE 正則表達式
By Kevin Song
概述
作用:操作字符串數據
public class RegexDemo {
public static void main(String[] args) {
String qq = "303043149";
//第一位1到9
//第二位0到9
//第二位0到9出現4到14次
String regex = "[1-9][0-9]{4,14}";//正則表達式
boolean b = qq.matches(regex);
System.out.println(qq+b);
}
public static void checkQQ(String qq) {
int len = qq.length();
if(len>=5 %% len<=15) {
if(!qq.startsWith("0")) {
try {
long l Long.parseLong(qq);
} catch(NumberFormatException e) {
System.out.println("非法字符");
}
} else {
System.out.println(qq+":不能0開頭");
}
} else {
System.out.println(qq+"長度錯誤");
}
}
}
常見的規則
字符類 | 含義 |
---|---|
[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(交集) |
[a-z&&[^bc]] | a 到 z,除了 b 和 c:[ad-z](減去) |
[a-z&&[^m-p]] | a 到 z,而非 m 到 p:[a-lq-z](減去) |
預定義字符類 | 含義 |
---|---|
. | 任何字符(與行結束符可能匹配也可能不匹配) |
\d | 數字:[0-9] |
\D | 非數字: [^0-9] |
\s | 空白字符:[ \t\n\x0B\f\r] |
\S | 非空白字符:[^\s] |
\w | 單詞字符:[a-zA-Z_0-9] |
\W | 非單詞字符:[^\w] |
邊界匹配器 | 含義 |
---|---|
^ | 行的開頭 |
$ | 行的結尾 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
\A | 輸入的開頭 |
\G | 上一個匹配的結尾 |
\Z | 輸入的結尾,僅用於最後的結束符(如果有的話) |
\z | 輸入的結尾 |
Greedy | 數量詞 |
---|---|
X? | X 一次或一次也沒有 |
X* | X 零次或多次 |
X+ | X 一次或多次 |
X{n} | X 恰好 n 次 |
X{n,} | X 至少 n 次 |
X{n,m} | 至少 n 次,但是不超過 m 次 |
Logical 運算符 | 含義 |
---|---|
XY | X 後跟 Y |
X | Y |
(X) | X,作爲捕獲組 |
Back 引用 | 含義 |
---|---|
\n | 任何匹配的 n^th 捕獲組 |
組的概念
((A)(B(C)))
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
組零始終代表整個表達式
常見功能
正則表達式對字符串的常見操作
- 匹配
- 使用String類中的matches方法
- 切割
- 使用String類中的split方法
- 替換
- 使用String類中的replaceAll方法
- 獲取
- 將正則表達式封裝成對象
- Pattern p = Pattern.compile(“a*b”);
- 通過正則對象的matcher方法字符串相關聯。獲取要對字符串操作的匹配器對象Matcher
- Matcher m = p.matcher(“aaaaab”);
- 通過Matcher匹配其對象的方法對字符串進行操作
- boolean b = m.matches();
- 將正則表達式封裝成對象
public class RegexDemo2 {
public static void main(String[] args) {
functionDemo_4();
}
/*獲取
*/
public static void functionDemo_4() {
String str = "da jia hao,ming tian bu fang jia!";
/*
獲取三個字母的單詞[a-z]{3}
*/
String regex = "\\b[a-z]{3}\\b";
//把正則封裝成對象
Pattern p = Pattern.compile(regex);
//通過正則對象獲取匹配器對象
Matcher m = p.matcher(str);
//使用Matcher對象的方法對字符串進行操作
//要獲取三個字母組成的單詞,用find()方法
System.out.println(str);
while(m.find()) {
System.out.println(m.group());//獲取匹配的子序列
System.out.println(m.start()+":"+m.end());//獲取字母開始和結束位置,包頭不包尾
}
}
//替換
public static void functionDemo_3() {
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
/*
把.用()封裝成組(.)
組的編號爲\\1
編號爲1的組出現過一次或者多次所以(.)\\1+
獲取編號1組裏的字母並且替換$1
*/
str = str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
String tel = "15800001111";//158****1111;
/*
前三個數封裝成編號爲1的組(\\d{3})
末四個數封裝成編號爲2的組(\\d{4})
*/
tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.println(tel);
}
//切割
public static void functionDemo_2(){
String str = "zhangsan xiaoqiang zhaoliu";
String[] names = str.split(" +");//一次或多次空格
String str = "zhangsan.xiaoqiang.zhaoliu";
String[] names = str.split("\\.");//用.來切,\\轉義
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
/*
把.用()封裝成組(.)
組的編號爲\\1
編號爲1的組出現過一次或者多次所以(.)\\1+
*/
String[] names = str.split("(.)\\1+");/
for(String name : names){
System.out.println(name);
}
}
//匹配
public static void functionDemo_1(){
//匹配手機號碼是否正確
String tel = "15800001111";
/*
第一位固定1
第二位是3,5,8中的一個[358]
第三位開始[0-9]用預定義字符類表示\\d重複9次
*/
String regex = "1[358]\\d{9}";
boolean b = tel.matches(regex);
System.out.println(tel+":"+b);
}
}
正則表達式練習
練習一
- 過濾信息
- We….neeeeeed..baa…aaack……uuu..up
- ip地址排序
- 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55
- 郵件地址校驗
public class RegexTest {
public static void main(String[] args) {
test_1();
}
public static void test_1 {
String str = "We....neeeeeed..baa...aaack......uuu..up";
//去掉...
str = str.replaceAll("\\.+"," ");
//替換疊詞
str = str.replaceAall("(.)\\1+","$1");
System.out.println(str);
}
public static void test_2 {
String ip_str = "192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55";
//爲了讓ip可以按照字符串順序比較,只要讓ip的每一段的位數相同
//補零,每一段加2個0
ip_str = ip_str.replaceAll("(\\d+)","00$1");
//00192.168.10.34 00127.0.0.1 003.3.3.3 00105.70.11.55
System.out.println(ip_str);
//每一段保留數字三位
ip_str = ip_str.replaceAll("0*(\\d{3})","$1");
//192.168.10.34 127.0.0.1 003.3.3.3 105.70.11.55
System.out.println(ip_str);
//把ip地址切出
str = str.split(" +");
TreeSet<String> ts = new TreeSet<String>();
for(String ip : ips) {
ts.add(ip);
}
for(String ip : ts) {
//0沒有或者多次後跟着連續數字
//用連續的數字替換帶0的那部分
System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
}
public static void test_3 {
String mail = "[email protected]";
/*
第一部分大小寫字母數字下劃線都可以一個或者多個[a-zA-Z0-9_]+
第二部分固定@
第三部分大小寫字母數字都可以一個或者多個[a-zA-Z0-9]+
第四部分(\\.字母出現1到3次)出現一次或者多次(\\.[a-zA-Z]{1,3})+
*/
String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+\\.[a-zA-Z]{1,3})+";
regex = "\\w+@\\w+(\\.\\w+)+";
boolean b = mail.matches(regex);
System.out.println(mail+":"+b);
}
}
}
網頁爬蟲
定義:在互聯網中獲取符合指定規則數據的程序
public class RegexTest2 {
public static void main(String[] args) throws IOException {
List<String> list = getMailsByWeb();
for(String mail : list){
System.out.println(mail);
}
}
public static List<String> getMailsByWeb() throws IOException {
//1, 讀取源文件
//BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
URL url = new URL("http://192.168.1.100:8080/myweb/mail.html");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(url.openStream()));
//2,對讀取的數據進行規則的匹配,從中獲取符合規則的數據
String mail_regex = "\\w+@\\w+(\\.\\w+)+";
List<String> list = new ArrayList<String>();
Pattern p = Pattern.compile(mail_regex);
String line = null;
while((line=bufIn.readLine())!=null){
Matcher m = p.matcher(line);
while(m.find()){
//3,符合規則的數據存儲到集合中
list.add(m.group());
}
}
return list;
}
public static List<String> getMails() throws IOException{
//1, 讀取源文件
BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
//2,對讀取的數據進行規則的匹配,從中獲取符合規則的數據
String mail_regex = "\\w+@\\w+(\\.\\w+)+";
List<String> list = new ArrayList<String>();
Pattern p = Pattern.compile(mail_regex);
String line = null;
while((line=bufr.readLine())!=null){
Matcher m = p.matcher(line);
while(m.find()){
//3,符合規則的數據存儲到集合中
list.add(m.group());
}
}
return list;
}
}