正则表达式

Java基础

浏览数:92

2019-8-21

AD:资源代下载服务

正则表达式

正则表达式是用于操作字符串的一个规则,正则表达式的规则使用了特殊的符号表示。

一、预定义字符类

.  任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9] 
\D 非数字:[^0-9] 除了0-9,其他都匹配
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]  包括a-z,A-Z,_,0-9
\W 非单词字符:[^\w]

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

public class MyRegex {
    
    public static void main(String[] args) {
        System.out.println("任意字符:"+("%".matches(".")));//true
        System.out.println("数字字符:"+("1".matches("\\d")));//true
        System.out.println("非数字字符:"+("@".matches("\\D")));//true
        
        System.out.println("空白字符:"+("").matches("\\s"));//false
        System.out.println("空白字符:"+(" ").matches("\\s"));//true
        System.out.println("空白字符:"+("\r").matches("\\s"));//true
        
        System.out.println("非空白字符:"+("a").matches("\\S"));//true
        System.out.println("非空白字符:"+("\n").matches("\\S"));//false
        
        System.out.println("单词字符:"+("_").matches("\\w"));//true
        System.out.println("单词字符:"+("#").matches("\\w"));//false
        
        System.out.println("非单词字符:"+("_").matches("\\W"));//false
        System.out.println("非单词字符:"+("#").matches("\\W"));//true
        
        System.out.println("");
        System.out.println("");
        System.out.println("");
    }

}

二、数量词

X?  X,一次或一次也没有
X*  X,零次或多次
X+  X,一次或多次
X{n}  X,恰好n次
X{n,}  X,至少n次
X{n,m}  X,至少n次,但是不超过m次

Demo:

public class MyRegex {
    
    public static void main(String[] args) {
        
        System.out.println("? 一次或一次也没有:"+("12".matches("\\d?")));//false
        System.out.println("* 零次或多次:"+("123".matches("\\d*")));//true
        System.out.println("+ 至少出现一次:"+("1".matches("\\d+")));//true
        System.out.println("{次数} 恰好出现n次:"+("12345678911".matches("\\d{11}")));//true
        System.out.println("{次数,} 至少要出现指定的次数:"+("123".matches("\\d{3,}")));//true
        System.out.println("{次数1,次数2} 指定出现次数的范围:"+("1234".matches("\\d{3,4}")));//true
        
    }

}

三、字符类

[abc]  a、b或c(简单类)
[^abc] 任何字符,除了a、b或c(否定)
[a-zA-Z] a到z或A到Z,两头的字母包括在内(范围)
[a-d[m-p]] a到d或m到p:[a-dm-p](并集) 或直接写 [a-dm-p]
[a-z&&[def]] d、e或f(交集) 或直接写 [def]

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

public class MyRegex {
    
    public static void main(String[] args) {
        
        System.out.println("d".matches("[abc]"));//false
        System.out.println("abc".matches("[abc]{3}"));//true 要匹配三个,必须加数量词
        System.out.println("%".matches("[^abc]"));//true
        System.out.println("字符可以是a-z之间:"+("a".matches("[a-z]")));//true
        System.out.println("字符可以是a-z、$、#之一:"+("a".matches("[a-zA-Z$#]")));//true
        
    }

}

需求:根据叠词进行切割字符串

public class Demo5 {
    
    public static void main(String[] args) {
        testSplit();
    }
    
    /*
     * 根据叠词进行切割
     */
    public static void testSplit() {
        String str = "大家家家明天天玩得得得得开心";
        //如果正则的内容需要被复用,那么需要对正则的内容进行分组。
        //分组的目的就是为了提高正则的复用性。组号不能指定,从1开始。
        String[] datas = str.split("(.)\\1+");
        System.out.println("数组的元素是:"+Arrays.toString(datas));
        //数组的元素是:[大, 明, 玩, 开心]
    }

}

():分组,分组的目的是为了让正则的内容被复用起来,组号从1开始。

((A)(B(C))):
第一组:((A)(B(C)))
第二组:(A)
第三组:(B(C))
第四组:(C)

package mydemo;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Demo5 {
    
    public static void main(String[] args) {
        testSplit();
        replaceTest();
    }
    
    /*
     * 根据叠词进行切割
     */
    public static void testSplit() {
        String str = "大家家家明天天玩得得得得开心";
        //如果正则的内容需要被复用,那么需要对正则的内容进行分组。
        //分组的目的就是为了提高正则的复用性。组号不能指定,从1开始。
        String[] datas = str.split("(.)\\1+");
        System.out.println("数组的元素是:"+Arrays.toString(datas));
        //数组的元素是:[大, 明, 玩, 开心]
        
    }
    /**
     * 替换
     */
    public static void replaceTest() {
        //还原为: 我要学编程
        String str = "我我我我我要要要学学编编编程程程";
        //如果需要在replaceAll方法正则的外部引用组内容,使用“$组号”
        str = str.replaceAll("(.)\\1+", "$1");
        System.out.println(str);//我要学编程
        
    }

}

四、边界匹配器

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

注意:\b 单词边界匹配器只是代表了单词的开始或者结束部分,不匹配任何的字符。

public class Demo6 {
    
    public static void main(String[] args) {
        System.out.println("hello world".matches("hello\\bworld"));//false
        System.out.println("hello world".matches("hello\\b world"));//true
        System.out.println("hello,world".matches("hello\\b,world"));//true
        //任何一个可以分割字符的符号都可以表示单词的结束
    }

}

五、正则对象

查找:
指定字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的正则对象匹配任意的字符串用于创建Matcher对象,执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

Pattern p = Pattern.compile("正则");
Matcher m = p.matcher("abc");
boolean b = m.matches();

1.Pattern(正则对象)

2.Matcher(匹配器对象)

匹配器使用的方法:

  • find():通知匹配器去匹配字符串,查找符合规则的字符串;找到返回true,否则返回false
  • group():获取符合规则的子串。

注意:使用group方法一定要先调用find方法让匹配器去查找符合规则的字符串,否则报错。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Demo7 {
    
    public static void main(String[] args) {
        //找出三个字母组成的单词
        String content = "wo shi yi ming cai niao xian zai zai nu li bian hao";
        String reg = "\\b[a-zA-Z]{3}\\b";
        //先把字符串的正则编译成Pattern对象
        Pattern p = Pattern.compile(reg);
        //使用正则对象匹配字符串用于生产一个Matcher对象
        Matcher m = p.matcher(content);
        
        while(m.find()) {
            System.out.println(m.group());
            /*
             * shi cai zai zai hao
             */
        }
        
    }

}

作者:JS_HCX