当前位置:   article > 正文

Java基础:爬虫_((?i)java)(?=8|11|17)

((?i)java)(?=8|11|17)

1.本地爬虫

Pattern:表示正则表达式

Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。在大串中去找符合匹配规则的子串。

1.2.获取Pattern对象

通过Pattern p = Pattern.compile("正则表达式");获得        

1.3.获取Matcher对象


通过Matcher m = p.matcher(str);获得  (m要在str中找符合p规则的小串)

其中, m为Matcher对象, p为正则表达式规则, str为要验证的字符串.

1.4.匹配文本中的对象


boolean b = m.find(); 表示拿着文本匹配器从头开始读取,寻找是否有满足规则的子串如果没有,方法返回false. 如果有,返回true。在底层记录子串的起始索引和结束索引+1.

1.5.截取文本匹配器的索引


String s = m.group(); 这时文本匹配器会停留在第一个匹配文本的结束索引+1处, 返回一个文本中索引为(0,4)不包含4索引的字符串(符合规则的). 

1.6.继续匹配和获取索引


重复第4步和第五步, 从上一次停留的地方开始向后查找.

第4步和第5步一般通过while(m.find()){}循环实现.

  1. package com.itheima.a08regexdemo;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. public class RegexDemo6 {
  5. public static void main(String[] args) {
  6. /* 有如下文本,请按照要求爬取数据。
  7. Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
  8. 因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台
  9. 要求:找出里面所有的JavaXX
  10. */
  11. String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
  12. "因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
  13. //1.获取正则表达式的对象
  14. Pattern p = Pattern.compile("Java\\d{0,2}");
  15. //2.获取文本匹配器的对象
  16. //拿着m去读取str,找符合p规则的子串
  17. Matcher m = p.matcher(str);
  18. //3.利用循环获取
  19. while (m.find()) {
  20. String s = m.group();
  21. System.out.println(s);
  22. }
  23. }
  24. private static void method1(String str) {
  25. //Pattern:表示正则表达式
  26. //Matcher: 文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
  27. // 在大串中去找符合匹配规则的子串。
  28. //获取正则表达式的对象
  29. Pattern p = Pattern.compile("Java\\d{0,2}");
  30. //获取文本匹配器的对象
  31. //m:文本匹配器的对象
  32. //str:大串
  33. //p:规则
  34. //m要在str中找符合p规则的小串
  35. Matcher m = p.matcher(str);
  36. //拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
  37. //如果没有,方法返回false
  38. //如果有,返回true。在底层记录子串的起始索引和结束索引+1
  39. // 0,4
  40. boolean b = m.find();
  41. //方法底层会根据find方法记录的索引进行字符串的截取
  42. // substring(起始索引,结束索引);包头不包尾
  43. // (0,4)但是不包含4索引
  44. // 会把截取的小串进行返回。
  45. String s1 = m.group();
  46. System.out.println(s1);
  47. //第二次在调用find的时候,会继续读取后面的内容
  48. //读取到第二个满足要求的子串,方法会继续返回true
  49. //并把第二个子串的起始索引和结束索引+1,进行记录
  50. b = m.find();
  51. //第二次调用group方法的时候,会根据find方法记录的索引再次截取子串
  52. String s2 = m.group();
  53. System.out.println(s2);
  54. }
  55. }

爬取数据练习

  1. package pacong;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. /*
  5. 需求:把下面文本中的座机电话,邮箱,手机号,热线都爬取出来。
  6. 来黑马程序员学习Java,
  7. 手机号:18512516758,18512508907或者联系邮箱:boniu@itcast.cn,
  8. 座机电话:01036517895,010-98951256邮箱:bozai@itcast.cn,
  9. 热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090
  10. */
  11. public class pacongdemo2 {
  12. public static void main(String[] args) {
  13. //400-?[1-9]\\d{2}-?[1-9]\\d{3}
  14. /*
  15. 分析:手机号: "1[3-9]\\d{9}"
  16. 联系邮箱:"\\w+@[\\w&&[^_]]{2,6}(\\.)([a-zA-Z]{2,3}){1,2}"
  17. 座机电话: "0\\d{2,3}-?[1-9]\\d{4,9};
  18. 热线电话: "400-?[1-9]\\d{2}-?[1-9]\\d{3};
  19. */
  20. String s = "来黑马程序员学习Java," +
  21. "电话:18512516758,18512508907" + "或者联系邮箱:boniu@itcast.cn," +
  22. "座机电话:01036517895,010-98951256" + "邮箱:bozai@itcast.cn," +
  23. "热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";
  24. String regex="(1[3-9]\\d{9})" +
  25. "|(\\w+@[\\w&&[^_]]{2,6}(\\.)([a-zA-Z]{2,3}){1,2})" +
  26. "|(0\\d{2,3}-?[1-9]\\d{4,9})" +
  27. "|(400-?[1-9]\\d{2}-?[1-9]\\d{3})";
  28. //1.获取正则表达式的对象
  29. Pattern p = Pattern.compile(regex);
  30. //2.获取文本匹配器的对象
  31. Matcher m = p.matcher(s);
  32. //利用m去读取s,会按照p的规则去找大串s里面的小串
  33. //3.利用循环获取每一个数据 while(m.find())
  34. while (m.find()) {
  35. System.out.println(m.group());
  36. }
  37. }
  38. }

结果

2.有条件的爬取数据


需求1:?相当于前面的java,起到占位符作用,后面的=表示在java后面跟随的数据,但是在获取的时候只获取前面部分.

需求2: 删除?= 表示java是8|11|17 或者是?:  ----:?相当于前面的java,起到占位符作用,:就表示我们要拼8|11|17的数据

需求3:除了8|11|17的文本不要 就输出?!即可

  1. package pacong;
  2. import java.util.regex.Matcher;
  3. import java.util.regex.Pattern;
  4. /*
  5. //Pattern:表示正则表达式
  6. Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。
  7. 在大串中去找符合匹配规则的子串。
  8. */
  9. public class pacongdemo4 {
  10. public static void main(String[] args) {
  11. /*
  12. 需求1:爬取版本号为8,11.17的Java文本,但是只要Java,不显示版本号。
  13. 需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8 Java11 Java17 Java17
  14. 需求3:爬取除了版本号为8,11.17的Java文本,
  15. */
  16. String s = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
  17. "因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
  18. //1.定义正则表达式
  19. //?理解为前面的数据Java
  20. //=表示在Java后面要跟随的数据
  21. //但是在获取的时候,只获取前半部分
  22. //需求1:
  23. String regex1 = "((?i)Java)(?=8|11|17)";
  24. String regex2 = "((?i)Java)(8|11|17)";
  25. String regex3 = "((?i)Java)(?:8|11|17)";
  26. Pattern P=Pattern.compile(regex3);
  27. Matcher m=P.matcher(s);
  28. while (m.find()){
  29. System.out.println(m.group());
  30. }
  31. }
  32. }

3.贪婪爬取和非贪婪爬取

 

贪婪爬取 : 在爬取数据的时候尽可能的多获取数据 (如:abbbbbbbbbbbb)

非贪婪爬取 : 在爬取数据的时候尽可能的少获取数据 (如:ab)

Java当中,默认的就是贪婪爬取

如果我们在数量词+或者*的后面加上问号,那么此时就是非贪婪爬取

贪婪爬取

  1. public class pacongdemo3 {
  2. public static void main(String[] args) {
  3. String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +
  4. "经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +
  5. "下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
  6. String regex="ab+";
  7. Pattern P=Pattern.compile(regex);
  8. Matcher M=P.matcher(s);
  9. while (M.find()) {
  10. System.out.println(M.group());
  11. }
  12. }
  13. }

结果:

非贪婪爬取

  1. public class pacongdemo3 {
  2. public static void main(String[] args) {
  3. String s = "Java自从95年问世以来,abbbbbbbbbbbbaaaaaaaaaaaaaaaaaa" +
  4. "经历了很多版木,目前企业中用的最多的是]ava8和]ava11,因为这两个是长期支持版木。" +
  5. "下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
  6. String regex="ab+?";
  7. Pattern P=Pattern.compile(regex);
  8. Matcher M=P.matcher(s);
  9. while (M.find()) {
  10. System.out.println(M.group());
  11. }
  12. }
  13. }

结果:

4.正则表达式在字符串中的使用

 先创建一个正则表达式规则, 然后传入字符串方法中, 返回的就是新的替换后的字符串或切割后的字符串数组了.        

String类的split()方法原型:

public String[] split(String regex)
//参数regex表示正则表达式。可以将当前字符串中匹配regex正则表达式的符号作为"分隔符"来切割字符串。

replaceAll用法

  1. public class pacongdemo5 {
  2. public static void main(String[] args) {
  3. /*
  4. 有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
  5. 要求1:把字符串中三个姓名之间的字母替换为vs
  6. 要求2:把字符串中的三个姓名切割出来*/
  7. String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";
  8. //细节:
  9. //方法在底层跟之前一样也会创建文本解析器的对象
  10. //然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去替换
  11. String regex="[\\w&&[^_]]+";
  12. String result = s.replaceAll(regex, "vs");
  13. System.out.println(result);
  14. }
  15. }

结果:

split用法

  1. package pacong;
  2. public class pacongdemo5 {
  3. public static void main(String[] args) {
  4. /*
  5. 有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
  6. 要求1:把字符串中三个姓名之间的字母替换为vs
  7. 要求2:把字符串中的三个姓名切割出来*/
  8. String s = "小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠";
  9. //细节:
  10. //方法在底层跟之前一样也会创建文本解析器的对象
  11. //然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去替换
  12. String regex="[\\w&&[^_]]+";
  13. /*String result = s.replaceAll(regex, "vs");
  14. System.out.println(result);*/
  15. //细节:
  16. //方法在底层跟之前一样也会创建文本解析器的对象
  17. //然后从头开始去读取字符串中的内容,只要有满足的,就用第二个参数去切割
  18. String[] str = s.split(regex);
  19. for (int i = 0; i < str.length; i++) {
  20. System.out.println(str[i]);
  21. }
  22. }
  23. }

结果:

5.分组

5.1.捕获分组

红色为第一组, 蓝色为第二组, 绿色为第三组

 

 

\\组号表示的就是把该组匹配的内容在匹配一遍, 两部分的内容相同. 

  1. package pacong;
  2. public class pacongdemo6 {
  3. public static void main(String[] args) {
  4. /*
  5. 需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
  6. 举例: a123a b456b 17891 &abc& a123b(false)
  7. \\组号:表示把第X组的内容再出来用一次
  8. */
  9. String regex1 = "(.).+\\1";
  10. //第一个.说的就是开头的字符是任意的,第2个点说的是中间的字符是任意的并且至少出现一次
  11. // \\1表示我要把第一组的数据a再用一次
  12. System.out.println("a123a".matches(regex1));
  13. System.out.println("b456b".matches(regex1));
  14. System.out.println("17891".matches(regex1));
  15. System.out.println("&abc&".matches(regex1));
  16. System.out.println("a123b".matches(regex1));
  17. System.out.println("--------------------------");
  18. //需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
  19. //举例: abc123abc b456b 123789123 &!@abc&!@ abc123abd(false)
  20. String regex2 = "(.+).+\\1";
  21. System.out.println("abc123abc".matches(regex2));
  22. System.out.println("b456b".matches(regex2));
  23. System.out.println("123789123".matches(regex2));
  24. System.out.println("&!@abc&!@".matches(regex2));
  25. System.out.println("abc123abd".matches(regex2));
  26. System.out.println("---------------------");
  27. //需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
  28. //举例: aaa123aaa bbb456bbb 111789111 &&abc&&
  29. //(.):把首字母看做一组
  30. // \\2:把首字母拿出来再次使用
  31. // *:作用于\\2,表示后面重复的内容出现0次或多次
  32. String regex3 = "((.)\\2*).+\\1";
  33. System.out.println("aaa123aaa".matches(regex3));
  34. System.out.println("bbb456bbb".matches(regex3));
  35. System.out.println("111789111".matches(regex3));
  36. System.out.println("&&abc&&".matches(regex3));
  37. System.out.println("aaa12aab".matches(regex3));
  38. System.out.println("---------------------");
  39. }
  40. }

  String regex3 = "((.)\\2*).+\\1";

分析:

首先开头的是任意字母(.) ,接着是重复上一个的字母 我们写\\1,\\表示把第X组的内容再出来用一次,这里是第一组,然后写一个*,这个*表示重复0次或者多次, 接着出现了.+,这个.+表示中间的字符,.表示任意字符,+表示至少出现一次, 然后最后一段的字符和开头的字符重复,所以我们把第一组括起来,然后根据分组规则,已括号为基准,所以里面的为第二组,所以改为\\2

(.)代表的是a字符 ,接着\\1重复上一个字符a的内容,然后*代表的是a字符至少出现0次,在写中间的字符(123),写一个(.+)就即可,然后写末端的aaa,怎么写呢,其实就是把前面的整体拿着用重复一次罢了,于是我们就要用括号括起来,就要把\\1改成\\2,后面写\\1 

结果:

  1. public class pacongdemo7 {
  2. public static void main(String[] args) {
  3. //需求:把重复的内容 替换为 单个的
  4. //学学 学
  5. //编编编编 编
  6. //程程程程程程 程
  7. // (.)表示把重复内容的第一个字符看做一组
  8. // \\1表示第一字符再次出现
  9. // + 至少一次
  10. // $1 表示把正则表达式中第一组的内容,再拿出来用
  11. String str = "我要学学编编编编程程程程程程";
  12. String regex="(.)\\1+";
  13. System.out.println(str.replaceAll(regex,"$1"));
  14. }
  15. }

结果:

5.2非捕获分组

特点:不占用组号

总结

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/805654
推荐阅读
相关标签
  

闽ICP备14008679号