Java笔记十五——正则表达式

正则表达式简介

学习正则表达式也可以参考这篇文章
正则表达式30分钟入门
正则表达式可以用字符串来描述规则,并用来匹配字符串,例如判断手机号,用正则表达式\d{11}:

boolean isValidMobileNumber(String s) {
    return s.matches("\\d{11}");
}

Java标准库的java.util.regex包内置了正则表达式引擎。
String regex = "20\\d\\d";

匹配规则

如果想匹配非ASCII字符,例如中文,那就用\u####的十六进制表示,例如:a\u548cc匹配字符串"a和c",中文字符和的Unicode编码是548c。

模糊匹配

  • 用 . 匹配一个任意字符。
  • \d 匹配0~9这样的数字
  • \w 可以匹配一个字母、数字或下划线,w的意思是word。
  • 用 \s 可以匹配一个空格字符,注意空格字符不但包括空格,还包括tab字符
  • \D 则匹配一个非数字。
  • \W 可以匹配 \w 不能匹配的字符,\S 可以匹配 \s 不能匹配的字符,这几个正好是反着来的。

重复匹配

  • 修饰符 * 可以匹配任意个字符,包括0个,如 \d* 可以匹配任意个数字
  • 修饰符 + 可以匹配至少一个字符,如 \d+ 可以匹配一个及以上个数字
  • 修饰符 ? 可以匹配0个或1个字符,如 \d? 可以匹配0个或1个数字
  • 修饰符 {} 可以精确指定字符数,如 \d{n},指定n个数字,\d{n,m}匹配n~m个数字,\d{n,}匹配至少n个数字

在这里插入图片描述
在这里插入图片描述

复杂匹配规则

用正则表达式进行多行匹配时,我们用^表示开头,$表示结尾。

匹配指定范围

[…]可以匹配范围内的字符,[1-9]匹配1-9,[0-9a-fA-F]匹配十六进制数字。0-9:字符0~9;a-f:字符a~f; A-F:字符A~F。
匹配6位十六进制数:[0-9a-fA-F]{6}。
[…]排除法,不包含指定范围的字符。比如匹配任意字符但不包括数字:[^1-9]{3}:匹配任意三个字符(但不能是数子1-9)

或规则匹配

用 | 连接的两个正则规则是或规则,例如,AB|CD表示可以匹配AB或CD。

使用括号

现在我们想要匹配字符串learn java、learn php和learn go怎么办?一个最简单的规则是learn\sjava|learn\sphp|learn\sgo,但是这个规则太复杂了,可以把公共部分提出来,然后用(…)把子规则括起来表示成learn\s(java|php|go)。(注意写成字符串的时候要用\\)
在这里插入图片描述

分组匹配

用正则匹配区号-电话号码这个规则。利用前面讲到的匹配规则,写出来很容易:
\d{3,4}-\d{6,8}。之后要分别提取区号和电话号码就不好提取了,用(…)先把提取规则分组:,把上述正则表达式变为(\d{3,4})-(\d{6,8})。
提取子串:引入java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回子串:

import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
        Matcher m = p.matcher("010-12345678");
        if (m.matches()) {
            String g1 = m.group(1);
            String g2 = m.group(2);
            System.out.println(g1);
            System.out.println(g2);
        } else {
            System.out.println("匹配失败!");
        }
    }
}

Pattern

String.matches()方法内部调用的就是Pattern和Matcher类的方法。
使用Matcher时,必须首先调用matches()判断是否匹配成功,匹配成功后,才能调用group()提取子串。

非贪婪匹配

贪婪匹配:任何一个规则,它总是尽可能多地向后匹配。
要让\d+尽量少匹配,让0*尽量多匹配,我们就必须让\d+使用非贪婪匹配。在规则\d+后面加个?即可表示非贪婪匹配。

import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d+?)(0*)");
        Matcher matcher = pattern.matcher("1230000");
        if (matcher.matches()) {
            System.out.println("group1=" + matcher.group(1)); // "123"
            System.out.println("group2=" + matcher.group(2)); // "0000"
        }
    }
}

搜索和替换

分割字符串

使用正则表达式分割字符串可以实现更加灵活的功能。String.split()方法传入的正是正则表达式。我们来看下面的代码:

"a b c".split("\\s"); // { "a", "b", "c" }
"a b  c".split("\\s"); // { "a", "b", "", "c" }
"a, b ;; c".split("[\\,\\;\\s]+"); // { "a", "b", "c" }

搜索字符串

find()是部分匹配,从当前位置开始匹配,找到一个匹配的子串,将移动下次匹配的位置。

import java.util.regex.*;

public class Main {
    public static void main(String[] args) {
        String s = "the quick brown fox jumps over the lazy dog.";
        Pattern p = Pattern.compile("\\wo\\w");
        Matcher m = p.matcher(s);
        while (m.find()) {
            String sub = s.substring(m.start(), m.end());
            System.out.println(sub);
        }
    }
}

替换字符串

String.replaceAll(),它的第一个参数是正则表达式,第二个参数是待替换的字符串:

public class Main {
    public static void main(String[] args) {
        String s = "The     quick\t\t brown   fox  jumps   over the  lazy dog.";
        String r = s.replaceAll("\\s+", " ");
        System.out.println(r); // "The quick brown fox jumps over the lazy dog."
    }
}

反向引用

把搜索到的指定字符串按规则替换,比如前后各加一个xxxx,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$1、$2来反向引用匹配到的子串。例如:

public class Main {
    public static void main(String[] args) {
        String s = "the quick brown fox jumps over the lazy dog.";
        String r = s.replaceAll("\\s([a-z]{4})\\s", " <b>$1</b> ");
        System.out.println(r);//the quick brown fox jumps <b>over</b> the <b>lazy</b> dog.
        //把任何4字符单词的前后用<b>xxxx</b>括起来。
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值