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();
}
}
}