正则表达式
什么是正则表达式
- 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”
如何做呢?
@Test
void test01(){
String str = " hello Java 123 ,456 ";
System.out.println(str.replaceAll("\\d+","9"));
}
/*
执行结果
hello Java 9 ,9
*/
在上例中 \\d+ 是我们的正则表达式,什么意思呢
其中 \d 意思是匹配 数字, 因为在java中 \ 有特殊含义,因此需要再加一个斜杠 写成 \\d
其中 + 的意思 是 重复一次或更多次,也就是多次匹配
因此 其中的数字都被替换。
- 二、
对于一串字符串 判断它是否是字母+数字+字母的格式
@Test
void 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]"));
}
/*
执行结果
true
false
*/
- 三、
对于一串字符串 判断它是否以 非数字开头 ,以字母结尾
@Test
void 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));
}
/*
执行结果
false
false
false
true
*/
Java中的java.util.regex 模块
利用Java 爬取 “ https://www.qq.com/” 的源码
@Test
void 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>
<a class="txt" href="https://sports.qq.com/kbsweb/game.htm?
</ul>
此时倘若 我想拿到其中的图片地址,应该怎么做呢
我们发现String 对象所提供的方法 是不能返回一部分筛选内容的,只能替换,分割,和判断是否符合正则
此时,我们就需要用到另一个模块
也就是 : Java中的java.util.regex 模块
Pattern类 和 Matcher 类
类 | 描述 |
---|---|
Matcher | 通过解释Pattern 在 character sequence 上执行匹配操作的引擎。 |
Pattern | 正则表达式的编译表示。 |
利用这两个类匹配并返回一个符合正则的字符串组
- 匹配字符串中的所有数字
@Test
void test04(){
String str = "adhadhad12dsdas55dsadhsdkj88dsadkh45dsadh44";
//拿到其中的数字
//使用Pattern 编写正则
Pattern pa = Pattern.compile("\\d+");
//使用Matcher匹配字符串
Matcher ma = pa.matcher(str);
//输出所有数字
while(ma.find()){
System.out.println(ma.group());
}
}
/*
执行结果:
12
55
88
45
44
*/
- 那如何拿到上例中的图片地址呢?
简单一点,我们将截取的这一部分作为一个字符串来使用
@Test
void test05(){
String str = "<ul class=\"news-list\">\n" +
" <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']\">\n" +
" <img src=\"//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0\" alt=\"免费看!正在视频直播NBA常规赛:马刺vs国王\">\n" +
" <i class=\"q-icons icon-play\"></i>\n" +
" <div class=\"desc undis\">1754673500</div>\n" +
" <a class=\"txt\" href=\"https://sports.qq.com/kbsweb/game.htm?\n" +
" </ul>";
// 第一步,编写正则
Pattern pa = Pattern.compile("<img.*src=\"(.*?)\".*>");
//匹配结果
Matcher ma = pa.matcher(str);
//输出结果
while(ma.find()){
System.out.println(ma.group());
}
}
/*
执行输出:
<img src="//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0" alt="免费看!正在视频直播NBA常规赛:马刺vs国王">
*/
可以看到,我们已经精准的筛选出了图片的标签
但是我们想要的是图片地址,而不是整个标签
可以看到,我所编写的正则是 : <img.src=\"(.)\".*>
前面说到: ()是表示一个组的,而这个组中所存放的也就是我们的链接
那此时,我们只需要拿到这个组中的内容即可
怎么做呢? 很简单
在上述几个例子中 我们使用到 Matcher类中的group方法
返回类型 | 方法 | 具体功能 |
---|---|---|
String |
group() |
返回上一个匹配项匹配的输入子序列。 |
String |
group(int group) |
返回上一个匹配操作期间给定组捕获的输入子序列。 |
可以看到,在匹配操作期间 会给每组一个序列号,我们只需传入序列号即可拿到组中的结果
@Test
void test05(){
String str = "<ul class=\"news-list\">\n" +
" <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']\">\n" +
" <img src=\"//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0\" alt=\"免费看!正在视频直播NBA常规赛:马刺vs国王\">\n" +
" <i class=\"q-icons icon-play\"></i>\n" +
" <div class=\"desc undis\">1754673500</div>\n" +
" <a class=\"txt\" href=\"https://sports.qq.com/kbsweb/game.htm?\n" +
" </ul>";
// 第一步,编写正则
Pattern pa = Pattern.compile("<img.*src=\"(.*?)\".*>");
//匹配结果
Matcher ma = pa.matcher(str);
//输出结果
while(ma.find()){
System.out.println(ma.group(1));
}
}
/*
执行输出
//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0
*/
此时我们也就拿到了这个图片的地址
当然,如果你要爬取这个图片,就必须在这个链接之前拼接 https:(这个肯定都会吧)
这是因为在浏览器中会自动拼接文章来源:https://www.toymoban.com/news/detail-467107.html
而java则不会文章来源地址https://www.toymoban.com/news/detail-467107.html
到了这里,关于Java中正则表达式的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!