Java中正则表达式的使用

正则表达式

什么是正则表达式

  • 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">1754673500div>
   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 = "";
    // 第一步,编写正则
    Pattern pa = Pattern.compile("");
    //匹配结果
    Matcher ma = pa.matcher(str);
    //输出结果
    while(ma.find()){
        System.out.println(ma.group());
    }
}
/*
执行输出:
免费看!正在视频直播NBA常规赛:马刺vs国王
*/

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

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

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

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

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

怎么做呢? 很简单

在上述几个例子中 我们使用到 Matcher类中的group方法

返回类型 方法 具体功能
String group() 返回上一个匹配项匹配的输入子序列。
String group(int group) 返回上一个匹配操作期间给定组捕获的输入子序列。

可以看到,在匹配操作期间 会给每组一个序列号,我们只需传入序列号即可拿到组中的结果

@Test
void test05(){
    String str = "";
    // 第一步,编写正则
    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则不会

你可能感兴趣的:(javase,正则表达式,java,开发语言)