正则表达式

什么是正则表达式

  • Regular Expression , 正则表达式, ⼀种使⽤表达式的⽅式对字符串 进⾏匹配的语法规则
  • 由一组持有特殊含义的字符串组成,通常用于匹配和替换文本
  • 正则的优点: 速度快, 效率⾼, 准确性⾼
  • 正则的缺点: 新⼿上⼿难度有 点⼉⾼

元字符

常见元字符

编号元字符匹配功能
1.匹配除换⾏符以外的任意字符
2\w匹配字⺟或数字或下划线
3\s匹配任意的空⽩符
4\d匹配数字
5\n匹配⼀个换⾏符
6\t匹配⼀个制表符
7^匹配字符串的开始
8$匹配字符串的结尾
9\W匹配⾮字⺟或数字或下划线
10\D匹配⾮数字
11\S匹配⾮空⽩符
12a|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方法

booleanmatches(String regex)告知此字符串是否匹配给定的 正则表达式

replaceAll方法

StringreplaceAll(String regex, String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

replaceFirst 方法

StringreplaceFirst(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”

如何做呢?

@Testvoid test01(){    String str = "  hello   Java 123 ,456 ";    System.out.println(str.replaceAll("\\d+","9"));}/*执行结果  hello   Java 9 ,9 */

在上例中 \\d+ 是我们的正则表达式,什么意思呢

其中 \d 意思是匹配 数字, 因为在java中 \ 有特殊含义,因此需要再加一个斜杠 写成 \\d

其中 + 的意思 是 重复一次或更多次,也就是多次匹配

因此 其中的数字都被替换。

  • 二、

对于一串字符串 判断它是否是字母+数字+字母的格式

@Testvoid 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]"));}/*执行结果truefalse*/
  • 三、

对于一串字符串 判断它是否以 非数字开头 ,以字母结尾

@Testvoid 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));}/*执行结果falsefalsefalsetrue*/

Java中的java.util.regex 模块

利用Java 爬取 “ https://www.qq.com/” 的源码

@Testvoid 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>   </ul>

此时倘若 我想拿到其中的图片地址,应该怎么做呢

我们发现String 对象所提供的方法 是不能返回一部分筛选内容的,只能替换,分割,和判断是否符合正则

此时,我们就需要用到另一个模块

也就是 : Java中的java.util.regex 模块

Pattern类 和 Matcher 类

描述
Matcher通过解释Pattern 在 character sequence 上执行匹配操作的引擎。
Pattern正则表达式的编译表示。

利用这两个类匹配并返回一个符合正则的字符串组

  • 匹配字符串中的所有数字
@Testvoid test04(){    String str = "adhadhad12dsdas55dsadhsdkj88dsadkh45dsadh44";    //拿到其中的数字    //使用Pattern 编写正则    Pattern pa = Pattern.compile("\\d+");    //使用Matcher匹配字符串    Matcher ma = pa.matcher(str);    //输出所有数字    while(ma.find()){        System.out.println(ma.group());    }}/*执行结果:1255884544*/
  • 那如何拿到上例中的图片地址呢?

简单一点,我们将截取的这一部分作为一个字符串来使用

@Testvoid test05(){    String str = "
    \n" + "
  • \n" + " */

可以看到,我们已经精准的筛选出了图片的标签

但是我们想要的是图片地址,而不是整个标签

可以看到,我所编写的正则是 : <img.src=\”(.)\”.*>

前面说到: ()是表示一个组的,而这个组中所存放的也就是我们的链接

那此时,我们只需要拿到这个组中的内容即可

怎么做呢” />\n” + 免费看!正在视频直播NBA常规赛:马刺vs国王\n” + \n” + ” 1754673500\n” + +

; // 第一步,编写正则 Pattern pa = Pattern.compile(); //匹配结果 Matcher ma = pa.matcher(str); //输出结果 while(ma.find()){ System.out.println(ma.group(1)); }}/*执行输出//inews.gtimg.com/newsapp_bt/0/202211166874049650056/0*/

此时我们也就拿到了这个图片的地址

当然,如果你要爬取这个图片,就必须在这个链接之前拼接 https:(这个肯定都会吧)

这是因为在浏览器中会自动拼接

而java则不会