找做网站技术人员,长春网络公司有哪些,河北网站建设价格,百度seo整站优化1.爬虫
我们在正则表达式的讲解中可以使用字符串的方法materchs()来匹配#xff0c;并且返回一个boolean值
String name lshhhljh;
System.out.println(name.matches(lsh{3}\\s{3}));
//true现在我们将利用正则表达式来爬取本地或者网站上的文本内…1.爬虫
我们在正则表达式的讲解中可以使用字符串的方法materchs()来匹配并且返回一个boolean值
String name lshhhljh;
System.out.println(name.matches(lsh{3}\\s{3}));
//true现在我们将利用正则表达式来爬取本地或者网站上的文本内容
a.本地文本
在此之前我们先学习一下两个会用到的类
Pattern表示正则表达式Matcher表示文本匹配器按照正则表达式的规则去读取字符串从头开始读取 Matcher表示在大串中获取符合规则的子串 我们来简单介绍一下这两个类
Pattern: 编译正则表达式用于将正则表达式字符串编译为一个模式对象这个编译后的对象可以高效的应用于多次匹配操作创建Matcher对象 Matcher用于对输入的字符串进行基于正则表达式的匹配操作。它与Pattern类紧密相连 通过例子来介绍这Matcher的方法 String s 文章包括各种文体的著作、作品如诗歌、戏剧、小说、 科学论文记叙文、议论文、说明文、应用文等等。 “千古文章未尽才”“文章千古事”“文章憎命达”“板凳要坐十年冷、文章不写一字空” “积句而成章积章而成篇”“言出为论下笔成章”等;
Pattern p Pattern.compile(文章);
Matcher matcher p.matcher(s);
boolean b matcher.find();
String s1 matcher.group();
System.out.println(s1);输出的结果是文章
boolean b matcher.find()
拿着文本匹配器从头开始读取,寻找是否有满足规则的子串
如果没有,方法返回false如果有,返回true。在底层记录子串的起始索引和结束索引1
String s1 matcher.group()
方法底层会根据find方法记录的索引进行字符的截取使用的是subString(起始索引,结束索引)包头不包尾。会把截取的小串进行返回。 所以find方法记录的索引才是结束索引1 但是上述的代码只能返回一个匹配的结果所以我们需要用到循环 Pattern p Pattern.compile(文章);Matcher matcher p.matcher(s);while (matcher.find()) {String s1 matcher.group();System.out.println(s1);}在代码中需要我们注意的是我们需要反复的调用find方法所以在while循环中要把find方法放进去。 find方法在多次调用时会依次往字符串的后面查找所以可以使用循环找到所有的结果 b.网络文本
说明略 代码示例
//创建一个URL对象
URL url new URL( spec: https://m.sengzan.com/jiaoyu/29104.html?ivk_sa1025883i);
//连接上这个网址
//细节:保证网络是畅通
URLConnection conn url. openConnection();
//创建一个对象去读取网络中的数据
BufferedReader br new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
//获取正则表达式的对象 pattern
String regex [1-9]\\d{17};
Pattern pattern Pattern.compile(regex);
//在读取的时候每次读一整行
while ((line br.readLine()) ! null) {//拿着文本匹配器的对象matcher按照pattern的规则去读取当前的这一行信息Matcher matcher pattern.matcher(line);while(matcher.find()){System.out.println(matcher.group());
}
br.close();2.带条件爬取
有的时候我们要对爬取的内容作限制和修改就用到了待条件爬取的规则
我们先看一个例子来自黑马程序员
有如下文本,请按照要求爬取数据。
Java自从95年问世以来,经历了很多版本,目前企业中用的最多
的是Java8和Java11,因为这两个是长期支持版本,
下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台需求1:爬取版本号为8,11,17的Java文本,但是只要Java,不显示版本号。
需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8Java11 Java17Java17
需求3:爬取除了版本号为8,11,17的Java文本,代码示例
String sJava自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,
因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台;
//1.定义正则表达式
String regex Java( ? 8|11|17);
Pattern p Pattern.compile(regex);
Matcher m p.matcher(s);
while(m.find()){System.out.println(m.group());
}输出的结果是4个Java String regex Java( ? 8|11|17)中括号中的部分只是当作了限制条件但是不会被输出。
? 在这里被当作占位符可以理解为前面的Java表示在占位符后面要跟的数据在这里是指要获取的子串的Java后面要跟的数据|表示“或者”的意思
因为第一个Java后面没有跟版本数字所以没有被打印 补充((?i)Java)( ? 8|11|17) ---- 第一个i表示Java在匹配的时候忽略大小写第二个 表示前面的((?i)Java) 需求二爬取版本号为8,11,17的Java文本。正确爬取结果为:Java8Java11 Java17Java17
第一种方法不使用? 作为占位符
String regex Java(8|11|17);第二种方法使用?
String regex Java(?:8|11|17);这两种方式都是可以满足上面的要求的 需求三爬取除了版本号为8,11,17的Java文本
String regex Java(?8|11|17);只需要修改正则表达式即可 在这里 表示去除的意思 4. 贪婪爬取和非贪婪爬取
我们前面介绍过正则表达式的数量词其中有这两个
* 表示 * 前面这个字符匹配零次或多次 表示 前面这个字符匹配一次或多次
那到底是匹配一次还是多次呢 在Java编译器种默认的匹配机制是贪婪爬取就是尽可能多的进行匹配
例如
abbbbbbbbbbbaaaaa这段字符如果正则表达式为ab
贪婪爬取abbbbbbbbbbb非贪婪爬取ab
默认的爬取方式为贪婪爬取我们怎么样使用非贪婪爬取呢
ab?ab*?
在正则表达式的后面加上一个?即可 5.正则表达式在字符串方法中的使用
返回值是字符串类型的方法中正则表达式的使用
方法名说明public boolean matches(String regex)判断字符串是否满足正则表达式的规则public String replaceAll(String regex,String newStr)按照正则表达式的规则进行替换public String[] split(String regex)按照正则表达式的规则切割字符串
代码示例:
有一段字符串:小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠
要求1:把字符串中三个姓名之间的字母替换为vs要求2:把字符串中的三个姓名切割出来
String s小诗诗dqwefqwfqwfwq12312小丹丹dqwefqwfqwfwq12312小惠惠;
//细节:
//方法在底层跟之前一样也会创建文本解析器的对象
//然后从头开始去读取字符串中的内容,只要有满足的,那么就用第二个参数去替换。
String resut1 s.replaceAll([\\w[^_]], vs);
System.out.println(resut1);//要求二
String[] arr s.split( regex: [\\w[^_]]);
for (int i 0; i arr.length; i) {System.out.println(arr[i]);
}第二个切割的方法就是按照正则表达式去切割把正则表达式匹配到的字符串当作断点切割 6.捕获分组和非捕获分组
题目的分组是针对正则表达式来说的 分组就是正则表达式中的小括号()
我们给出代码示例
//简易身份证号码
String regex1 \\w[\\w[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2});
//邮箱号
String regex2 [1-9]\d{16}(\\d|x|x);
//24小时时间的两种方式
String regex3 ([01]\\d|2[0-3]): [0-5]\\d: [0-5]\d
String regex4 ([01]\d|2[0-3])(:[0-5]\\d){2}用括号表示分组再使用分组进行复用 同时我们需要知道分组其实是有序号的
(\\d(\\d))(\\d)
1 2 3分组的序号是看左括号进行排序的
a.捕获分组
就是把这一组的数据捕获出来再使用一次 代码示例
//需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
//举例: abc123abc b456b 123789123 !abc! abc123abd(false)
String regex2 (.).\\1;
System.out.println(abc123abc.matches(regex2));
System.out.println(b456b.matches(regex2));
System.out.println(123789123.matches(regex2));
System.out.println(!abc!.matches(regex2));
System.out.println(abc123abd.matches(regex2));代码示例二
String str我要学学编编编编程程程程程程”;
//需求:把重复的内容 替换为 单个的
//学学
//编编编编
//程程程程程程
//(.)表示把重复内容的第一个字符看做一组
//\\1 表示第一字符再次出现
//至少一次
//$1 表示把正则表达式中第一组的内容,再拿出来用
String result str.replaceAll( regex:(.)\\1, replacement: $1);
System.out.println(result);String result str.replaceAll( regex:(.)\\1, replacement: $1)这行代码在进行替换的时候仍然使用了第一组的内容。所以使用了$组号 因为是在正则表达式的外部使用组号所以需要使用这个符号$ b.非捕获分组
非捕获分组: 分组之后不需要再用本组数据,仅仅是把数据括起来。
符号含义举例( ?: 正则)获取所有Java( ?: 8|11|17)( ? 正则)获取前面部分Java( ? 8|11|17)( ?! 正则)获取不是指定内容的前面部分Java( ?! 8 | 11|17) 非捕获分组不占用组号仅仅是把数据括起来并且括号内的数据是否进行获取还要看非捕获分组的分类
代码示例前面的Java字符串案例这里不再赘述