java的正则表达式
1 正则表达式的规则
字符类:
[abc] 代表匹配abc其中任意一个字符。
[^abc] 代表匹配除abc以外的任意一个字符。
[a-c] 代表匹配abc其中任意一个字符。
[a-cA-C] 代表匹配小写abc或大写ABC中任意一个字符。
预定义字符:
\d 代表匹配0-9之间任意一个数字。
\D 代表非数字。
\w 代表匹配[a-zA-Z_0-9]中任意一个字符。
\W 代表匹配除了[a-zA-Z_0-9]以外的任意一个字符。
\s 代表匹配一个空格。
\S 代表匹配一个非空格。
. 代表匹配任意一个字符。
边界词:
^ 代表行的开头;
$ 代表行的结尾;
\b 代表单词的边界;
数量词:
?代表匹配0次或1次;
+代表匹配1次或多次;
*匹配0次或多次;
{n}匹配n次
{n,}匹配至少n次
{n,m}匹配至少n次,不超过m次。
注意:正则表达式是一个字符匹配一位。
2 正则表达式的使用
2.1 匹配内容
第一步:定义规则;
第二步:通过字符串的matches方法进行匹配。如果该方法返回true,代表匹配成功;否则匹配失败。
package demo01正则表达式;
/*
* 使用正则匹配手机号
*/
public class Demo01 {
public static void main(String[] args) {
// 定义规则
String regex = "1\\d{10}";
// 调用字符串的matches进行匹配
String phone = "13a22223456";
boolean isMatch = phone.matches(regex);
System.out.println(isMatch ? "匹配" : "不匹配");
}
}
2.2 替换内容
第一步:定义规则;
第二步:调用字符串的replaceAll方法替换符合正则表达式的内容;
/*
* 使用正则实现替换功能
*/
public class Demo02 {
public static void main(String[] args) {
String content = "请联系我13522234567请联系我13622234567请联系我14522234567请联系我18522234567";
// 定义规则
String regex = "1\\d{10}";
// 使用replaceAll方法把手机号码替换成###########
content = content.replaceAll(regex, "###########");
System.out.println(content);
}
}
2.3 字符串切割
第一步:定义规则;
第二步:调用字符串的split方法按照正则表达式进行切割,该方法返回一个String[]数组。
package demo01正则表达式;
/*
* 使用正则实现字符串切割
*/
public class Demo03 {
public static void main(String[] args) {
String ip = "192.168.0.100";
// 定义规则
String regex = "\\.";
// 按照ip的一点进行切割
String[] arr = ip.split(regex);
System.out.println("开始打印...");
for (String s : arr) {
System.out.println(s);
}
}
}
2.4 查找
第一步:把正则表达式编译成Pattern对象;
第二步:创建匹配器;
第三步:调用匹配器的find()和group()方法查找符合正则表达式的内容;
find(): 查找下一个符合正则表达式的内容,如果找到返回true,否则返回false;
group():获取以前匹配到的字符串内容;
package demo01正则表达式;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo04 {
public static void main(String[] args) {
String content = "请联系我13522234567请联系我13622234567请联系我14522234567请联系我18522234567";
// 定义规则,然后把规则编译成Pattern对象
String regex = "1\\d{10}";
Pattern p = Pattern.compile(regex);
// 创建匹配器对象
Matcher m = p.matcher(content);
// 调用匹配器的find和group查找符合正则表达式的内容
/*boolean b = m.find();
if (b) {
String s = m.group();
System.out.println(s);
}*/
while (m.find()) {
String s = m.group();
System.out.println(s);
}
}
}
3 爬虫实现
3.1 网络资源的分析
主要先对网站源代码进行分析,找规则 ,然后得出正则表达式
举例(爬取贴吧的所有标题):
第一步:查看网页的源码。http://tieba.baidu.com/f?kw=%E4%B8%AD%E5%9B%BD%E5%A5%BD%E5%A3%B0%E9%9F%B3
第二步:查找标题对应的标签。
<a rel="noreferrer" href="/p/6198751550" title="整天尴尬扯国籍黑的人,有王力宏在的卫视是不是都要抵制?" target="_blank" class="j_th_tit ">整天尴尬扯国籍黑的人,有王力宏在的卫视是不是都要抵制?</a>
<a rel="noreferrer" href="/p/6197308075" title="自从王力宏发出加入中国好声音的消息,吧内谢霆锋的部分粉丝开始" target="_blank" class="j_th_tit ">自从王力宏发出加入中国好声音的消息,吧内谢霆锋的部分粉丝开始</a>
<a rel="noreferrer" href="/p/6197557059" title="王粉不要再碰瓷谢霆锋" target="_blank" class="j_th_tit ">王粉不要再碰瓷谢霆锋</a>
第三步:分析标题所使用标签的规则。例如
String regex = "target=\"_blank\" class=\"j_th_tit\">.*?</a>";
上面.*代表匹配任意0个或多个任意字符。默认情况下,正则表达式会尝试匹配尽可能多的字符,我们称为贪婪模式。而上面在.*后面加上?,代表匹配尽量少的字符。
3.2 爬取网页
第一步:创建一个URL对象,该对象可以用于绑定网络资源的地址。
URL url = new URL("URL地址");
第二步:创建URLConnection对象,该对象用于与URL资源建立连接。
URLConnection connection = url.openConnection();
第三步:获取资源的内容;
InputStream inputStream = connection.getInputStream();
第四步:通过InputStream对象读取资源的内容(I/O操作)。
第五步:关闭connection。
connection.disconnect();
例如:爬取百度贴吧(http://tieba.baidu.com/f?kw=中国好声音)。
package demo02爬虫;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class Demo02 {
public static void main(String[] args) throws IOException {
// 创建URL对象
URL url = new URL("http://tieba.baidu.com/f?kw=%E4%B8%AD%E5%9B%BD%E5%A5%BD%E5%A3%B0%E9%9F%B3");
// 创建URLConnection对象,建立远程连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 获取InputStream
InputStream inputStream = connection.getInputStream();
// 把inputStream对象转换BufferedReader对象
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
// 使用StringBuilder字符串缓冲类,用于拼接字符串。
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
// 把读取到的内容先保存在StringBuilder内部维护的字符串数组中。
// 当调用tostring方法的时候,StringBuilder才会把字符串数组中的内容放入在内存中。
sb.append(line);
line = br.readLine();
}
String tieba = sb.toString();
System.out.println(tieba);
// 关闭连接
connection.disconnect();
}
}
3.3 抓取网页的内容
这里通过上面正则表达式查找的步骤相同。
package demo02爬虫;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo02 {
public static void main(String[] args) throws IOException {
// 爬取网页
String tieba = getHtmlContent();
// 定义规则,然后编译成Pattern
String regex = "target=\"_blank\" class=\"j_th_tit \">.*?</a>";
Pattern p = Pattern.compile(regex);
// 创建匹配器对象
Matcher m = p.matcher(tieba);
// 调用find和group方法获取匹配内容
while (m.find()) {
String title = m.group();
title = title.replace("target=\"_blank\" class=\"j_th_tit \">", "");
title = title.replace("</a>", "");
System.out.println(title);
}
}
// 爬取网页
private static String getHtmlContent() throws MalformedURLException,
IOException {
// 创建URL对象
URL url = new URL("http://tieba.baidu.com/f?kw=%E4%B8%AD%E5%9B%BD%E5%A5%BD%E5%A3%B0%E9%9F%B3");
// 创建URLConnection对象,建立远程连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 获取InputStream
InputStream inputStream = connection.getInputStream();
// 把inputStream对象转换BufferedReader对象
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
// 使用StringBuilder字符串缓冲类,用于拼接字符串。
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
// 把读取到的内容先保存在StringBuilder内部维护的字符串数组中。
// 当调用tostring方法的时候,StringBuilder才会把字符串数组中的内容放入在内存中。
sb.append(line);
line = br.readLine();
}
String tieba = sb.toString();
//System.out.println(tieba);
// 关闭连接
connection.disconnect();
return tieba;
}
}
上一篇: 【读书笔记】设计模式第五章第六章收获
下一篇: 软件构造总结