1.正則表達式:
語法:
1.普通字符
\d : 任意一個數字,0~9
\w : 任意一個字母或者數字或者下劃線,0~9 ,A~Z , a~z , _
\s : 空格,製表符,換行符等
. : 匹配任意字符,但是不能匹配換行符。
[ab5@] //匹配 a,b,5,@中任意一個字符
[^123] //匹配123之外的任意一個字符
[2-8] //匹配2到8之間任意一個字符
[^2-8a-g] //匹配 出了2到8,a到9之外的任意一個字符
正則表達式的特殊符號,被包含到中括號中,則失去特殊意義,除了^,-之外
2.量詞
{n} : 表達式重複n次。
{m,n} : 表達式至少重複m次,最多重複n次。
{m,} : 表達式至少重複m次。
?: 匹配表達式0次或者1次,相當於{0,1}。
+: 表達式至少出現1次,相當於{1}。
*: 表達式不出現或出現任意次,相當於{0}。
// 量詞默認貪婪模式
\d{3,6} ----------->取6個 如: 123456
//非貪婪
\d{3,6}? ----------->取3個 如: 123
3.字符邊界 (匹配的是位置,不是字符)
^ : 字符串開的地方,匹配 -------------> 左邊界
$: 字符串結束的地方,匹配 -------------> 右邊界
\b : 字符串邊界的地方,匹配 -------------> 左右邊界
- 但是\b匹配的位置:前面的字符好後面的字符不全是\w。
4.選擇符和分組
| : 左右兩邊表達式之間"或"關係,匹配左邊或右邊
() : 捕獲組
- 在被修飾匹配次數的時候,括號中的表達式可以作爲正體被修飾。
- 取匹配結果的時候,括號中的表達式匹配到的內容可以被單獨得到。
重點:反向引用 (\nnn (n是多位) ------> \1,\10,\100 )
- 每一對()會分配一個編號,使用()的捕獲根據左括號的順序從1開始自動編號
- 通過反向引用,可以對分組已捕獲的字符串進行引用
([a-z]{2}) ---------> goto gogo myname dodo
對應的是上面的字符串
([a-z]{2})\1 ---------> 查到的是 gogo dodo (就是以左括號爲準)
預搜索(斷言)
(?=xxx): 以xxx結尾。
(?<=xxx): 以xxx開頭。
(?!=xxx) : 不以xxx結尾。
(?<!xxx): 不以xxx開頭
(?=xxx) // 斷言自身出現的位置的後面能匹配表達式xxx。不包括xxx
// 例如: going doing sjd222
[a-z]+(?=ing)
結果 : go do
[a-z]+(?=\d+)
結果 : sjd
2.練習
1.電話號碼驗證
-
電話號碼由數字和 “-” 構成。
-
如果電話號碼中包含有區號,那麼區號爲三位或者四位,首位是0。
-
區號用 "-"和其他部分隔開。
-
移動電話號碼爲11位。
-
例子:010-8889999
-
(0\d{2,3}-\d{7,9})|(1[35789]\d{9})
-
(1[35789]\d{9})
-
2.電子郵箱地址驗證
-
用戶名: 字母,數字,中劃線,下劃線組成。
-
@
-
網址:字母,數字組成
-
小數點 “ .”。
-
組織域名:2-4位字母組成
-
不區分的大小寫
-
[\w\-]+@[a-z0-9A-Z]+(\.[A-Za-z]{2,4}){1,2}
3.JAVA練習
package com.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
//在這個字符串:asfssjadj153513,是否符合指定的正則表達式
Pattern p = Pattern.compile("\\w+");
//創建Matcher
Matcher m = p.matcher("asfssjad&&j153513");
/* boolean matches = m.matches();
boolean b = m.find();
System.out.println(matches);
//查詢的是&& 之後的匹配子序
System.out.println(b);*/
while(m.find()){
System.out.println(m.group()); // 匹配整個匹配整個表達式
System.out.println(m.group(0)); // 匹配整個匹配整個表達式
//1,2,3,4 是分組的
}
}
}
package com.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo2 {
public static void main(String[] args) {
//把數字換成#
Pattern pattern = Pattern.compile("[0-9]");
Matcher matcher = pattern.matcher("ssu333dn22dn2da222");
String s = matcher.replaceAll("#");
System.out.println(s);
}
}
package com.regex;
public class RegexDemo3 {
public static void main(String[] args) {
String s = "skjak32dakj27y2d";
String[] split = s.split("\\d+");
for (String str : split){
System.out.println(str);
}
}
}
爬取網易首頁,找出http的所有鏈接
package com.regex;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class SocketRegex {
public static void main(String[] args) {
String content = getUrlContent("http://www.163.com");
//System.out.println(content);
// 取出a鏈接裏面的東西
// Pattern pattern = Pattern.compile("<a[\\s\\S].+?</a>");
//取出超鏈接
Set<String> set = getFinalResult(content, "href=\"([a-z]{4}([\\w\\s./:]+?))\"");
set.stream().forEach(result -> System.out.println(result));
}
private static Set<String> getFinalResult(String content,String regex) {
Set<String> set = new HashSet<String>();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
set.add(matcher.group(1));
}
return set;
}
private static String getUrlContent(String urlString) {
StringBuilder sb = new StringBuilder();
try {
URL url = new URL(urlString);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream(), Charset.forName("gbk")));
String temp = "";
while((temp = bufferedReader.readLine())!=null){
sb.append(temp+"\n");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
return sb.toString();
}
}
}