正则表达式笔记

1、正则表达式:

        1. 正则表达式其实就是一种规则,有自己特殊的应用,其作用就是针对字符串进行操作

        2. 正则:就是用于操作字符串的一种规则,其中这些规则使用了一些字符表示

 

2、预定义字符类

        .   点 表示任何字符(与行结束符可能匹配也可能不匹配)

        \d 数字:[0-9]

        \D 非数字: [^0-9]

        \s 空白字符:[ \t \n \x0B \f \r]

        \S 非空白字符:[^\s]

        \w 单词字符:[a-z A-Z _ 0-9]

        \W 非单词字符:[^\w]

注意:任何预定义字符在没有加上数量词之前,都只能匹配一个字符而已。

2.1 预定义字符案例

// . 表示任意字符,匹配任意字符都返回true
        System.out.println(". 匹配任意字符?" + ("a".matches(".")));
        System.out.println();

        //  \d 表示数字0-9其中一位,匹配0-9返回true,其他返回false
        System.out.println("\\d 匹配任意数字[0-9]?" + ("3".matches("\\d")));
        System.out.println();

        //  \D 表示非数字,即非\d [^0-9],只要不是数字0-9即返回true
        System.out.println("\\D 匹配任意非数字字符:?" + ("a".matches("\\D")));
        System.out.println();

        //  \s 表示空白字符 [ \t \n \x0B \f \r ],匹配这些空调字符返回true,其他返回false
        System.out.println("\\s 匹配任意空白字符?" + ("\t".matches("\\s")));
        System.out.println();

        //  \S 表示非空表字符 [^\s]
        System.out.println("\\S 匹配任意非空白字符?" + ("s".matches("\\S")));
        System.out.println();

        //  \w 表示单词字符:[a-zA-Z_0-9],匹配大小写a-z,数字0-9,下划线_,返回true,其他返回false
        System.out.println("\\w 匹配任意单词字符?" + ("_".matches("\\w")));
        System.out.println();

        //  \W 表示非单词字符:[^\w]
        System.out.println("\\W 匹配任意非单词字符:?" + ("#".matches("\\W")));

    执行结果:

. 匹配任意字符?true

\d 匹配任意数字:(匹配一位数字[0-9])?true

\D 匹配任意非数字字符:?true

\s 匹配任意空白字符?true

\S 匹配任意非空白字符?true

\w 匹配任意单词字符?true

\W 匹配任意非单词字符:?true

3、Greedy 数量词

X  ?          一次或一次也没有(?表示 最多出现一次X字符)
X  *         零次或多次(* 表示 任意次)
X  +         一次或多次(+ 表示 最少出现一次X字符)
X  {n}    恰好n次(出现n次X字符)
X  {n,}       至少n次(最少出现n次X字符)
X  {n,m}   至少n次,最多m次(出现n<=x<=m 次X字符)

3.1 Greedy 数量词案例:

// X ?: 问号 表示一次或一次也没有(最多出现一次X字符)
System.out.println("? 表示 最多一次(0次)?" + ("".matches("\\w?")));// true
System.out.println("? 表示 最多一次(1次)?" + ("a".matches("\\w?")));// true
System.out.println("? 表示 最多一次(2次)?" + ("aa".matches("\\w?")));// false
System.out.println();

//  X *: 星号 表示零次或多次(出现任意次数的X字符)
System.out.println("*表示出现 任意次(0次)?" + ("".matches("\\d*")));// true
System.out.println("*表示出现 任意次(1次)?" + ("1".matches("\\d*")));// true
System.out.println("*表示出现 任意次(2次)?" + ("11".matches("\\d*")));// true
System.out.println();

// X +: 加号表示一次或多次(最少出现一次)
System.out.println("+表示出现1次或多次(0次)?" + ("".matches("\\d+")));// false
System.out.println("+表示出现1次或多次(1次)?" + ("1".matches("\\d+")));// true
System.out.println("+表示出现1次或多次(2次)?" + ("11".matches("\\d+")));// true
System.out.println();

// X {n}: {n}大括号里写次数,表示正好出现n次X字符
System.out.println("{2} 表示恰好出现2次(1次)?" + "1".matches("\\d{2}"));// false
System.out.println("{2} 表示恰好出现2次(2次)?" + "11".matches("\\d{2}"));// true
System.out.println("{2} 表示恰好出现2次(3次)?" + "111".matches("\\d{2}"));// false
System.out.println();

// X {n,}: 表示至少出现n次X字符,n次或以上为true,n次以下为false
System.out.println("{2,} 表示恰好出现2次(1次)?" + "1".matches("\\d{2,}"));// false
System.out.println("{2,} 表示恰好出现2次(2次)?" + "11".matches("\\d{2,}"));// true
System.out.println("{2,} 表示恰好出现2次(3次)?" + "111".matches("\\d{2,}"));// true
System.out.println();

// X {n,m}: 表示最少出现n次,最多出现m次
System.out.println("{2,4} 表示至少出现2次,最多出现4次(1次)?" + ("1".matches("\\d{2,4}")));// false
System.out.println("{2,4} 表示至少出现2次,最多出现4次(2次)?" + ("11".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出现2次,最多出现4次(3次)?" + ("122".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出现2次,最多出现4次(4次)?" + ("1333".matches("\\d{2,4}")));// true
System.out.println("{2,4} 表示至少出现2次,最多出现4次(5次)?" + ("14444".matches("\\d{2,4}")));// false
System.out.println();

    执行结果:

? 表示 最多一次(0次)?true
? 表示 最多一次(1次)?true
? 表示 最多一次(2次)?false

* 表示出现 任意次(0次)?true
* 表示出现 任意次(1次)?true
* 表示出现 任意次(2次)?true

+ 表示出现1次或多次(0次)?false
+ 表示出现1次或多次(1次)?true
+ 表示出现1次或多次(2次)?true

{2} 表示恰好出现2次(1次)?false
{2} 表示恰好出现2次(2次)?true
{2} 表示恰好出现2次(3次)?false

{2,} 表示恰好出现2次(1次)?false
{2,} 表示恰好出现2次(2次)?true
{2,} 表示恰好出现2次(3次)?true

{2,4} 表示至少出现2次,最多出现4次(1次)?false
{2,4} 表示至少出现2次,最多出现4次(2次)?true
{2,4} 表示至少出现2次,最多出现4次(3次)?true
{2,4} 表示至少出现2次,最多出现4次(4次)?true
{2,4} 表示至少出现2次,最多出现4次(5次)?false

 

4、范围表示

    [abc]: 表示 a、b 或 c
    [^abc]: 表示 任何字符,除了 a、b 或 c
    [a-zA-Z]: 表示 a-z 或 A-Z,两头的字母包括在内
    [a-d[m-p]]: 表示 a-d 或者 m-p 的并集
    [bcd&&[def]]: 表示bcd与def的交集
    [a-z&&[^bc]]: 表示 a-z,除了 b 和 c:[a或者d-z]
    [a-z&&[^m-p]]: 表示 a-z和 【a-z 除去m-p】的交集,即 a-l 或者 q-z

4.1 范围表示 案例

// [abc]:表示匹配a、b 或 c其中的一个字符(简单类)
System.out.println("[abc]表示匹配a或b或c为true(a)?" + ("a".matches("[abc]")));//true
System.out.println("[abc]表示匹配a或b或c为true(e)?" + ("e".matches("[abc]")));//false
System.out.println();

// [^abc]:表示匹配任何字符(1个),除了 a、b 或 c(否定)
    System.out.println("[^abc]表示匹配除abc之外的任意一个字符(a)?" + 
("a".matches("[^abc]")));//false
    System.out.println("[^abc]表示匹配除abc之外的任意一个字符(3)?" + 
("3".matches("[^abc]")));//true
    System.out.println();

//[a-zA-Z]:表示匹配 a到z 或 A到Z 中的任意一个字符,两头的字母包括在内(范围)
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(F)?" + ("F".matches("[a-zA-Z]")));//true
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(f)?" + ("f".matches("[a-zA-Z]")));//true
    System.out.println("[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(3)?" + ("3".matches("[a-zA-Z]")));//false
    System.out.println();

//[a-d[m-p]]:表示 a到d 或 m到p中的任意一个字符(并集)
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(B)?" + ("B".matches("[a-d[m-p]]")));//false
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(b)?" + ("b".matches("[a-d[m-p]]")));//true
    System.out.println("[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(m)?" + ("m".matches("[a-d[m-p]]")));//true
    System.out.println();

// [bcd&&[def]]: 表示bcd和def的交集,结果是字符d
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(d)?" + 
("d".matches("[bcd&&[def]]")));// true
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(e)?" + 
("e".matches("[bcd&&[def]]")));// false
    System.out.println("[bcd&&[def]]表示abcd和def的交集(即d)(f)?" +
 ("f".matches("[bcd&&[def]]")));// false
    System.out.println();

// [a-z&&[^bc]]	表示a到z 和 【a-z除了b和c】的交集,结果是a或d-z中的一个字符
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(a)?" + "a".matches("[a-z&&[^bc]]"));// true
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(b)?" + "b".matches("[a-z&&[^bc]]"));// false
    System.out.println("[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(z)?" + "z".matches("[a-z&&[^bc]]"));// true
    System.out.println();

// [a-z&&[^m-p]]:表示 a-z 与【a-z减去m-p】的交集,结果是a-l和q-z中的一个字符
    System.out.println("[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(a)?" + "a".matches("[a-z&&[^m-p]]"));// true
    System.out.println("[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(m)?" + "m".matches("[a-z&&[^m-p]]"));// false
    System.out.println("[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(z)?" + "z".matches("[a-z&&[^m-p]]"));// true
    System.out.println();

执行结果:

[abc]表示匹配a或b或c为true(a)?true
[abc]表示匹配a或b或c为true(e)?false

[^abc]表示匹配除abc之外的任意一个字符(a)?false
[^abc]表示匹配除abc之外的任意一个字符(3)?true

[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(F)?true
[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(f)?true
[a-zA-Z]表示匹配a-z和A-Z之中的任意一个字符(3)?false

[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(B)?false
[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(b)?true
[a-d[m-p]]表示匹配a-d或m-p之中的任意一个字符(m)?true

[bcd&&[def]]表示abcd和def的交集(即d)(d)?true
[bcd&&[def]]表示abcd和def的交集(即d)(e)?false
[bcd&&[def]]表示abcd和def的交集(即d)(f)?false

[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(a)?true
[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(b)?false
[a-z&&[^bc]]表示a到z 和 【a-z除了b和c】的交集(z)?true

[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(a)?true
[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(m)?false
[a-z&&[^m-p]]表示 a-z 与【a-z减去m-p】的交集(z)?true

注意:正则表达式中 大括号{ n }表示次数,中括号[a-z]表示范围。

注意:范围词里边,不管内容有多长,没有数量词的配合,只能匹配其中的一个字符。

5、分组()

     为了提高规则的复用,用()小括号来对正则表达式的字节进行分组,每个括号都有一个编号,编号从1开始。可以通过编号来完成对该规则的调用。注意:需要对编号规则进行转义,\\1就表示获取第一组规则,\\2代表获取第二组规则,以此类推。

5.1 案例

// 需求:将手机号的中间四位使用*号代替
// 第一步,找到手机号,将手机号分组成三部分,前三位是第一组,中间四位是第二组,最后四位是第三组
// 第二步,将手机号的中间4位用 * 号代替
public static void testReplace() {
    String str = "联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119";
    // 使用小括号将正则表达式分为3组。
    String reg = "(1[34578][0-9])(\\d{4})(\\d{4})";
    // // $1表示匹配到的第1组子表达式,$3表示第三组子表达式。$1,$2,$3这种格式直接写在正则表达式中是错误的,它只是起到一个占位的作用。
    String s = str.replaceAll(reg, "$1****$3");
    System.out.println("替换后的帖子是:" + s);
}

执行结果:

替换后的帖子是:联系我:135****2119联系我:135****2119联系我:135****2119联系我:135****2119联系我:135****2119联系我:135****2119

6.边界匹配器

^行的开头
$行的结尾
\b单词边界
\B非单词边界
\A输入的开头
\G上一个匹配的结尾
\Z输入的结尾,仅用于最后的结束符(如果有的话)
\z输入的结尾

7.正则表达式的四种常见应用

1. 匹配

     常用方法 matches(reg)

2. 切割

    常用方法 split(reg)

3. 替换

    常用方法 replace(reg,replacement) 、replaceAll(reg,replaement)

4. 查找

    此时需要使用正则表达式对象

7.1 正则表达式的常见应用案例:

public static void main(String[] args) {
    // 1.匹配应用
    System.out.println("使用正则表达式匹配手机号:" + matchesPhone("13933395149"));
    System.out.println("使用正则表达式匹配固话:" + matchesTel("0315-7421005"));
    System.out.println();

    // 切割应用
    System.out.println("使用正则表达式按照空格进行切割:" + Arrays.toString(testSplit1("   今 天   大 家   玩  的  开   心  ")));
    System.out.println("使用正则表达式按照重叠词进行切割:" + Arrays.toString(testSplit2("大家家家家家玩玩的的的的开心心心!!!")));

    // 替换应用
    testReplace1();
    testReplace2();

    // 查找应用
    getWord();;

}

// 需求:正则表达式匹配手机号,第一位是1,第二位345789,后边全是数字,一共11位
public static String matchesPhone(String phone) {
    String reg = "1[34578]\\d{9}";
    return phone.matches(reg) ? "合法手机号" : "非法手机号";
}

// 需求:正则表达式匹配固话 区号首位是0,长度3-4位,主机号,首位不能是0,长度7-8位
public static String matchesTel(String tel) {
    String reg = "0\\d{2,3}-[1-9]\\d{6,7}";
    return tel.matches(reg) ? "合法固话" : "非法固话";
}

// 按照空格进行切割
public static String[] testSplit1(String string) {
    return string.split(" +");
}

// 根据重叠词进行切割
public static String[] testSplit2(String string) {
    // 如果正则的内容需要被复用,那么需要对正则的内容进行分组,分组的目的是 为了提高正则的复用性。
    return string.split("(.)\\1+(.)\\2+");
}


// 需求:将字符串中的手机号中间4位替换成****号
public static void testReplace1() {
    String str = "联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119";
    String reg = "(1[34578][0-9])(\\d{4})(\\d{4})";
    // $1表示匹配到的第1组子表达式,$3表示第三组子表达式。$1,$2,$3这种格式直接写在正则表达式中是错误的,它只是起到一个占位的作用
    String s = str.replaceAll(reg, "$1****$3");
    System.out.println("替换后的帖子是:" + s);
}


// 需求:"我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程",将字符串还原成 "我要学编程"。
// 分析:第一步:先将所有点去掉。 第二步将所有重叠字进行切割并保留一个
public static void testReplace2() {
    String str = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程";
    // 将所有.去掉
    str = str.replaceAll("\\.+", "");
    System.out.println(str);
    // 将重叠字进行叠词处理,并保留一个
    str = str.replaceAll("(.)\\1+", "$1");
    System.out.println(str);
}

 

8、通用的正则表达式

    手机号: ^1(3[\\d]|4[579]|5[0-3[5-9]]|6[2[5-7]]|7[1-3[5-8]]|8[0-9]|9[0-3[5-9]])\\d{8}$

    邮箱:    ^[0-9a-zA-Z]+([-\\w])+@([\\w]+\\.)+[a-z]{2,}$     

                   或

                  ^[a-z0-9A-Z]+[-|a-z0-9A-Z._]+@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-z]{2,}$

           手机号和邮箱的通用表达式有多重写法,可以根据自己的习惯编写,比如将 [0-9] 写成 [\\d],或者将 [0-3[5-9]] 写成 [0-9&&[^4]],找到规律就好。勤加练习,应付工作上的一般状况还是很轻松的。

 

 

9、正则对象

  1、查找需要使用的对象:
        Pattern:正则对象
        Matcher:匹配器

    2、正则表达式的编译表示形式。
          指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,
      依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
          因此,典型的调用顺序是
                 Pattern p = Pattern.compile("a*b");
                 Matcher m = p.matcher("aaaaab");
                 boolean b = m.matches();

    3、匹配器要使用的方法
        find():通知匹配器去匹配字符串,查找符合规则的子串。如果能查找到符合规则的子字符串,返回true,否则返回false
        group():获取符合规则的子串

        注意:使用group方法之前,一定要使用find方法去查找符合规则的字符串,否则报错。

9.1 案例

使用正则对象查找符合正则表达式规则的内容:需求 在字符串中查找由三个字母组成的单词

    // 需求:在字符串中获取由三个字母组成的单词
    public static void getWord() {
        String str = "da jia hao , ming tian bu fang jia , xie xie !";
        String reg = "\\b[a-zA-Z]{3}\\b";

        // 首先要把字符串的正则编译成Pattern正则对象,\b表示单词的边界
        Pattern pattern = Pattern.compile(reg);

        // 使用正则对象匹配字符串,用于产生一个Matcher 匹配器对象
        Matcher matcher = pattern.matcher(str);

        // matcher.find():判断字符串中是否存在符合正则表达式的内容
        // matcher.group():获取符合正则规则的字符串内容
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值