正则表达式(下)

正则表达式

作用二:在一段文本中查找满足要求的内容

本地爬虫和网络爬虫

这一段我仅仅使用案列进行演示

在此之前我们需要用到两个类:

pattern,他是属于java.util.regex.Pattern包下的类

用于定义正则表达式的典型的调用顺序是

Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches();

Matcher,文本匹配器,也是属于java.util.regex.Matcher包下的类,按照正则表达式的规则去读取字符串,从头开始读取。

话不多说开撸

  • 本地爬虫

    import java.util.regex.Matcher; import java.util.regex.Pattern; public class Demo2 { public static void main(String[] args) { //Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下个长期 //支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台 //要求:找到文本中JavaXX String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本," + "下个长期支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台"; //获取正则表达式的对象 Pattern p=Pattern.compile("Java\\d{0,2}"); //获取文本匹配器的对象 //m:文本匹配的对象 //str:大串 //p:规则 //m要在str中找复合p规则的小串 Matcher m=p.matcher(str); //拿着文本匹配器从头开始读取,寻找是否右满足规则的子串 //如果没有,方法返回false //如果有,返回true,再记录子串的起始索引和结束索引+1 //为什么是+1呢,可以思考String截取字符串的方法subSring //boolean flag=m.find(); while (m.find()){ String s=m.group(); System.out.println(s); } } }
  • 网络爬虫

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Demo3 { public static void main(String[] args) throws IOException { /*需求:把下面网址中属于身份证的内容爬取出来 http://liaocheng.dzwww.com/lcxw/202009/t20200902_6516416.htm*/ URL url=new URL("http://liaocheng.dzwww.com/lcxw/202009/t20200902_6516416.htm"); URLConnection conn=url.openConnection(); BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; String regex="[1-9]\\d{17}"; Pattern pattern=Pattern.compile(regex); while ((line=br.readLine())!=null){ System.out.println(line); Matcher matcher= pattern.matcher(line); while (matcher.find()){ System.out.println(matcher.group()); } } br.close(); } }

这段代码不建议练习,因为网页编码问题

题目练习

import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test1 { public static void main(String[] args) { /*需求:把下面文本中的电话,邮箱,手机号,热线都爬取出来。 * 来学习Java, * 电话:15196768904 18881104189, * 或者联系邮箱:zongjie@itcast.cn, * 座机号码:01036517895,010-98951256 * 邮箱:bozai@itcast.cn, * 热线电话:400-618-9090.400-618-4000,4006184000,4006189090 * */ //手机的正则:1[3-9]\\d{9} //邮箱的正则: \\w+@[\\w&&[^_]]{2,6}(\.[a-zA-Z]{2,3}){1,2} //座机的正则:0\\d{2,3}-?[1-9]\\d{4,9} //热线的正则:400-?[1-9]\\d{2}-?[1-9]\\d{3} String s="来学习Java,\n" + "电话:15196768904 18881104189,\n" + "或者联系邮箱:zongjie@itcast.cn,\n" + "座机号码:01036517895,010-98951256\n" + "邮箱:bozai@itcast.cn,\n" + "热线电话:400-618-9090.400-618-4000,4006184000,4006189090"; String regex="(1[3-9]\\d{9})|(\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2})|(0\\d{2,3}-?[1-9]\\d{4,9})|(400-?[1-9]\\d{2}-?[1-9]\\d{3})"; //获取正则表达式的对象 Pattern p=Pattern.compile(regex); //获取文本匹配器的对象 //用m取读取s,会按照p的规则找里面的小串 Matcher m=p.matcher(s); //利用循环获取每一个数据 while (m.find()){ System.out.println(m.group()); } } }
import java.util.regex.Matcher; import java.util.regex.Pattern; public class Demo4 { public static void main(String[] args) { //Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下个长期 //支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台 //需求1:爬取版本号为8,11,17的Java文本,但是只要Java,不显示版本号 //需求2:爬取版本号为8,11,17的Java文本,但是只要Java,显示版本号 //需求2:爬取除了版本号为8,11,17的Java文本 String s="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下个长期\n" + "支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台"; //1.书写正则表达式 //?理解为前面的数据Java //=表示在Java后面要跟随的数据 //但是在获取的时候,只获取前半部分 //需求1 String regex1="((?i)Java)(?=8|7|11|17)"; //需求2 String regex2="((?i)Java)(8|7|11|17)"; //需求3 String regex3="((?i)Java)(?!8|7|11|17)"; Pattern p=Pattern.compile(regex3); Matcher m=p.matcher(s); while (m.find()){ System.out.println(m.group()); } } }

条件爬取

import java.util.regex.Matcher; import java.util.regex.Pattern; public class Demo4 { public static void main(String[] args) { //Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下个长期 //支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台 //需求1:爬取版本号为8,11,17的Java文本,但是只要Java,不显示版本号 //需求2:爬取版本号为8,11,17的Java文本,但是只要Java,显示版本号 //需求2:爬取除了版本号为8,11,17的Java文本 String s="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个是长期支持版本,下个长期\n" + "支持的版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台"; //1.书写正则表达式 //?理解为前面的数据Java //=表示在Java后面要跟随的数据 //但是在获取的时候,只获取前半部分 //需求1 String regex1="((?i)Java)(?=8|7|11|17)"; //需求2 String regex2="((?i)Java)(8|7|11|17)"; //需求3 String regex3="((?i)Java)(?!8|7|11|17)"; Pattern p=Pattern.compile(regex3); Matcher m=p.matcher(s); while (m.find()){ System.out.println(m.group()); } } }

贪婪爬取和非贪婪爬取

abbbbbbbbbbbbbbbbbb

贪婪爬取:ab+

非贪婪爬取:ab

Java中,默认的是贪婪爬取,如果我们在数量词+*后面加上问号,就是非贪婪爬取

识别正则的方法两个方法

方法名 说明

public String[] matches(String regex) 判断字符串是否满足正则表达式的规则

public String replaceAll(String regex,String newStr) 按照正则表达式的规则替换

public String[] split(String regex) 按照正则表达hi的规则切割字符串

演示

public class Demo5 { public static void main(String[] args) { //有一段字符串:小明dasdasdqwd小刚dfakfdhgui小智 //要求1:把字符串中三个姓名之间的字母替换为vs //要求2:把字符串中的姓名切割出来 String s="小明dasdasdqwd小刚dfakfdhgui小智"; /*String result=s.replaceAll("[\\w&&[^_]]+","vs"); System.out.println(result);*/ String [] arr=s.split("[\\w&&[^_]]+"); for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }

捕获和非捕获

分组

分组就是一个小括号,每组是有组号的,也就是序号

  • 规则1:从1开始,连续不间断

  • 规则2:以左括号为基准,最左边是第一组,其次是第二组,依次类推

    (\\d+)(\\d+)(\\d)

    (\\d+(\\d+))(\\d)

public class Demo6 { public static void main(String[] args) { //捕获分组的练习 //捕获分组就是把这一组的数据捕获出来,再用一次 //需求1:判断一个字符串的开始字符和结束字符是否一致,只考虑一个字符 //举例:a123a b4556b 12314 //拆分成三部分,第一部分是任意字符(.),第二部分也是任意的多个.+,第三部分就复用第一组的//1 String regex1="(.).+\\1"; System.out.println("a123a".matches(regex1)); System.out.println("b4556b".matches(regex1)); System.out.println("12314".matches(regex1)); //需求2:判断一个字符串的开始字符和结束字符是否一致,可以有多个字符 //举例:abc123abc bc4556bc 12314 String regex2="(.+).+\\1"; System.out.println("abc123abc".matches(regex2)); System.out.println("bc4556bc".matches(regex2)); System.out.println("12314".matches(regex2)); //需求3:判断一个字符串的开始字符和结束字符是否一致,开始部分内部每个字符也需要一致 //举例:abc1212abc bc4556bc 123123 String regex3="(.+)\\1"; System.out.println("abc1212abc".matches(regex3)); System.out.println("bc4556bc".matches(regex3)); System.out.println("123123".matches(regex3)); } }
public class Demo7 { public static void main(String[] args) { //题目:解决口吃 //将字符串:我要学学学编编编编编编编程程程程程程 //改为:我要学编程 String str="我要学学学编编编编编编编程程程程程程"; //分析replaceAll()方法作用就是替换掉正则表达式的内容 //(.)\1+ +代表至少一次 //$1 表示把正则表达式中的第一组的内容,再拿出来用 String new_str= str.replaceAll("(.)\\1+","$1"); System.out.println(new_str); } }

小结

  • 组号的特点:即上文规则

  • 捕获分组:

如果后续还要使用本组的数据

​ 正则内部使用:\\组号

​ 正则外部是同:$组号

  • 非捕获分组

    分组之后不需要再使用本组数据,仅仅是把数据括起来

符号 含义 举例

(?:正则) 获取所有 Java(?:8|11|17)

(?=正则) 获取前面部分 Java(?=8|11|17)

(?!正则) 获取不是指定内容的前面部分 Java(?!8|11|17)


__EOF__

本文作者七岁就很浪
本文链接https://www.cnblogs.com/qisui/p/16873622.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   喜欢七岁就很浪  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
  1. 1 青石巷 魏琮霏
  2. 2 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  3. 3 世间美好与你环环相扣 柏松
  4. 4 形容 沈以诚
  5. 5 把回忆拼好给你 王贰浪
  6. 6 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  7. 7 纸短情长 烟把儿
  8. 8 心做し 双笙(陈元汐)
  9. 9 盗将行 花粥,马雨阳
  10. 10 A Little Story Valentin
  11. 11 心似烟火 陈壹千
  12. 12 烟袋斜街 接个吻,开一枪,SaMZIng
  13. 13 还是分开 张叶蕾
イエスタデイ(翻自 Official髭男dism) - 茶泡饭,春茶,kobasolo
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 藤原聡

作曲 : 藤原聡

何度失ったって

取り返して見せるよ

雨上がり 虹がかかった空みたいな

君の笑みを

例えばその代償に

誰かの表情を

曇らせてしまったっていい

悪者は僕だけでいい

本当はいつでも

誰もと思いやりあっていたい

でもそんな悠長な理想論は

ここで捨てなくちゃな

遥か先で 君へ 狙いを定めた恐怖を

遥か先で 君へ 狙いを定めた恐怖を

どれだけ僕は

はらい切れるんだろう?

半信半疑で 世間体

半信半疑で 世間体

気にしてばっかのイエスタデイ

ポケットの中で怯えたこの手は

まだ忘れられないまま

「何度傷ついたって

「何度傷ついたって

仕方ないよ」と言って

うつむいて君が溢した

儚くなまぬるい涙

ただの一粒だって

僕を不甲斐なさで 溺れさせて

理性を奪うには十分過ぎた

街のクラクションもサイレンも

街のクラクションもサイレンも

届きやしないほど

遥か先へ進め 身勝手すぎる恋だと

遥か先へ進め 身勝手すぎる恋だと

世界が後ろから指差しても

振り向かず進め必死で

振り向かず進め必死で

君の元へ急ぐよ

道の途中で聞こえたSOS さえ

気づかないふりで

バイバイイエスタデイ ごめんね

バイバイイエスタデイ ごめんね

名残惜しいけど行くよ

いつかの憧れと違う僕でも

ただ1人だけ 君だけ

守るための強さを

何よりも望んでいた この手に今

遥か先へ進め

遥か先へ進め

幼すぎる恋だと

世界が後ろから指差しても

迷わずに進め 進め

2人だけの宇宙へと

ポケットの中で震えたこの手で今

君を連れ出して

未来の僕は知らない

だから視線は止まらない

謎めいた表現技法

意味深な君の気性

アイラブユーさえ

アイラブユーさえ

風に 飛ばされそうな時でも

不器用ながら繋いだ この手はもう

決して離さずに

虹の先へ

点击右上角即可分享
微信分享提示