正则表达式
什么是正则表达式
- Regular Expression , 正则表达式, ⼀种使⽤表达式的⽅式对字符串 进⾏匹配的语法规则
- 由一组持有特殊含义的字符串组成,通常用于匹配和替换文本
- 正则的优点: 速度快, 效率⾼, 准确性⾼
- 正则的缺点: 新⼿上⼿难度有 点⼉⾼
元字符
常见元字符
编号 | 元字符 | 匹配功能 |
---|---|---|
1 | . | 匹配除换⾏符以外的任意字符 |
2 | \w | 匹配字⺟或数字或下划线 |
3 | \s | 匹配任意的空⽩符 |
4 | \d | 匹配数字 |
5 | \n | 匹配⼀个换⾏符 |
6 | \t | 匹配⼀个制表符 |
7 | ^ | 匹配字符串的开始 |
8 | $ | 匹配字符串的结尾 |
9 | \W | 匹配⾮字⺟或数字或下划线 |
10 | \D | 匹配⾮数字 |
11 | \S | 匹配⾮空⽩符 |
12 | a|b | 匹配字符a或字符b |
13 | () | 匹配括号内的表达式,也表示⼀个组 |
14 | […] | 匹配字符组中的字符 |
15 | [^…] | 匹配除了字符组中字符的所有字符 |
量词
编号 | 元字符 | 功能 |
---|---|---|
1 | * | 重复零次或更多次 |
2 | + | 重复⼀次或更多次 |
3 | ? | 重复零次或⼀次 |
4 | {n} | 重复n次 |
5 | {n,} | 重复n次或更多次 |
6 | {n,m} | 重复n到m次 |
匹配模式
编号 | 元字符 | 功能 |
---|---|---|
1 | .* | 贪婪匹配 |
2 | .*? | 惰性匹配 |
str: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游戏啊
reg: 玩⼉.*?游戏 (惰性匹配)
此时匹配的是: 玩⼉吃鸡游戏
reg: 玩⼉.*游戏 (贪婪匹配)
此时匹配的是: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游
戏
java中 String 对象提供的一些正则使用方法
matches方法
boolean | matches(String regex) | 告知此字符串是否匹配给定的 正则表达式 |
---|
replaceAll方法
String | replaceAll(String regex, String replacement) | 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
---|
replaceFirst 方法
String | replaceFirst(String regex, String replacement) | 使用给定的 replacement 替换此字符串匹配给定的的第一个子字符串。 |
---|
split 方法
String[] | split(String regex) | 根据给定 正则表达式 的匹配拆分此字符串。 |
---|
String[] | split(String regex, int limit) | 根据匹配给定的正则表达式来拆分此字符串。 |
---|
参数
- regex : 正则表达式
- replacement:替换字符
- limit:参数控制模式应用的次数
Java实例
- 一、
对于一串字符 ” hello Java 123 ,456 “
将 所有的 数字 替换为 “9”
如何做呢?
@Testvoid test01(){ String str = " hello Java 123 ,456 "; System.out.println(str.replaceAll("\\d+","9"));}/*执行结果 hello Java 9 ,9 */
在上例中 \\d+ 是我们的正则表达式,什么意思呢
其中 \d 意思是匹配 数字, 因为在java中 \ 有特殊含义,因此需要再加一个斜杠 写成 \\d
其中 + 的意思 是 重复一次或更多次,也就是多次匹配
因此 其中的数字都被替换。
- 二、
对于一串字符串 判断它是否是字母+数字+字母的格式
@Testvoid test02(){ String str1 = "a1b"; String str2 = "1a1"; System.out.println(str1.matches("[a-zA-Z]\\d[a-zA-Z]")); System.out.println(str2.matches("[a-zA-Z]\\d[a-zA-Z]"));}/*执行结果truefalse*/
- 三、
对于一串字符串 判断它是否以 非数字开头 ,以字母结尾
@Testvoid test03(){ String regex = "^\\D.*[a-zA-Z]$"; System.out.println("12dads45".matches(regex)); System.out.println("dsadsguakgdk12".matches(regex)); System.out.println("12dbsjka".matches(regex)); System.out.println("..dd456sds".matches(regex));}/*执行结果falsefalsefalsetrue*/
Java中的java.util.regex 模块
利用Java 爬取 “ https://www.qq.com/” 的源码
@Testvoid test(){ try { //url模块可以建立连接 URL url = new URL("https://www.qq.com/"); URLConnection con = null; BufferedReader br = null; try { con = url.openConnection(); br = new BufferedReader(new InputStreamReader(con.getInputStream(), "gb2312")); String msg = null; while((msg=br.readLine())!=null){ System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); }finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } catch (MalformedURLException e) { e.printStackTrace(); }}
执行打印输出,https://www.qq.com/的前端源码
这里只截取部分输出结果:
<ul class="news-list"> <li class="video-box click-pop-play" data-beacon-expo="qn_elementid=rmss_1&qn_event_type=show" data-beacon-click="qn_elementid=rmss_1&qn_event_type=click" bosszone="rmss_1" bossvv="vv_rmss" dt-imp-once="true" dt-eid="em_video" dt-params="vid=1754673500&dt_element_path=['em_video','em_content_card']"> <img src="//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0" alt="免费看!正在视频直播NBA常规赛:马刺vs国王"> <i class="q-icons icon-play"></i> <div class="desc undis">1754673500</div> </ul>
此时倘若 我想拿到其中的图片地址,应该怎么做呢
我们发现String 对象所提供的方法 是不能返回一部分筛选内容的,只能替换,分割,和判断是否符合正则
此时,我们就需要用到另一个模块
也就是 : Java中的java.util.regex 模块
Pattern类 和 Matcher 类
类 | 描述 |
---|---|
Matcher | 通过解释Pattern 在 character sequence 上执行匹配操作的引擎。 |
Pattern | 正则表达式的编译表示。 |
利用这两个类匹配并返回一个符合正则的字符串组
- 匹配字符串中的所有数字
@Testvoid test04(){ String str = "adhadhad12dsdas55dsadhsdkj88dsadkh45dsadh44"; //拿到其中的数字 //使用Pattern 编写正则 Pattern pa = Pattern.compile("\\d+"); //使用Matcher匹配字符串 Matcher ma = pa.matcher(str); //输出所有数字 while(ma.find()){ System.out.println(ma.group()); }}/*执行结果:1255884544*/
- 那如何拿到上例中的图片地址呢?
简单一点,我们将截取的这一部分作为一个字符串来使用
@Testvoid test05(){ String str = "\n"
+ " \n" + " */
可以看到,我们已经精准的筛选出了图片的标签
但是我们想要的是图片地址,而不是整个标签
可以看到,我所编写的正则是 : <img.src=\”(.)\”.*>
前面说到: ()是表示一个组的,而这个组中所存放的也就是我们的链接
那此时,我们只需要拿到这个组中的内容即可
怎么做呢” />\n” + ” \n” + ” \n” + ” 1754673500\n” + ” + ”
“
; // 第一步,编写正则 Pattern pa = Pattern.compile(““); //匹配结果 Matcher ma = pa.matcher(str); //输出结果 while(ma.find()){ System.out.println(ma.group(1)); }}/*执行输出//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0*/此时我们也就拿到了这个图片的地址
当然,如果你要爬取这个图片,就必须在这个链接之前拼接 https:(这个肯定都会吧)
这是因为在浏览器中会自动拼接
而java则不会