首页 > 技术文章 > java中的正则表达式And Pattern And Macher

java-quan 2020-09-02 13:52 原文

在哪里??

java.util.regex包下有两个用于正则表达式的类, 一个是Matcher类, 另一个Pattern

 

 

简单例子

public class RegexLeaning {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("[a-z]{3}");
        Matcher m = p.matcher("bac");
        System.out.println(m.matches());
    }
    //结果:true
}

Pattern可以理解为一个模式, 字符串需要与某种模式进行匹配,上面设置的就是匹配a-z中的三个字母

Matcher可以理解为模式匹配某个字符串后产生的结果

Pattern类中的compile方法, 也就是说对我们传入的正则表达式编译后得到一个模式对象. 而这个经过编译后模式对象, 
会使得正则表达式使用效率会大大提高, 并且作为一个常量, 它可以安全地供多个线程并发使用

 

第一类正则表达式:

/**
     * .    Any character (may or may not match line terminators), 任意字符
     * X?    X, once or not at all       零个或一个
     * X*    X, zero or more times       零个或多个
     * X+    X, one or more times        一个或多个
     * X{n}    X, exactly n times          x出现n次
     * X{n,}    X, at least n times     x出现至少n次
     * X{n,m}    X, at least n but not more than m times 出现n~m次

第二类正则表达式:

  /**
         * \d    A digit: [0-9]          数字
         * \D    A non-digit: [^0-9]     非数字
         * \s    A whitespace character: [ \t\n\x0B\f\r] 空格
         * \S    A non-whitespace character: [^\s]       非空格
         * \w    A word character: [a-zA-Z_0-9]          数字字母和下划线
         * \W    A non-word character: [^\w]             非数字字母和下划线
         */

 

[]用于描述一个字符的范围

 

 

Pattern类:

 

 

/**
         * 将给定的正则表达式编译并赋予给Pattern类
         *
         *    public static Pattern compile(String regex, int flags)
         *     public static Pattern compile(String regex)
         */
        Pattern p = Pattern.compile("a+",Pattern.CASE_INSENSITIVE);
        System.out.println(p.flags());//2

        /**
         * String pattern() 返回该pattern对象所编译的正则表达式
         */
        Pattern p1 = Pattern.compile("\\d+");
        System.out.println(p1.pattern());//\d+

 

String[] split()
  /**
         * String[] split() 按regex分隔字符串,返回字符串数组
         *
         *  public String[] split(CharSequence input, int limit)
         *  intput:需要财富的字符串序列
         *  limit是控制应用模式的次数,影响数组的长度
         *      n>0     :模式至少应用n-1次,数组长度不大于n。
         *      n != 正数:模式应用无限制,并且数组可任意长度
         *      n =0    :模式应用无限制,并且数组可任意长度,丢弃尾部空字符串
         *
         *
         *   public String[] split(CharSequence input)
         */

 

 Pattern p2 = Pattern.compile("\\d+");
        String[] str = p2.split("全12电话89和收集");
        String[] str2 = p2.split("全12电话89和收集",2);
        System.out.println(Arrays.toString(str));//[全, 电话, 和收集]
        System.out.println(Arrays.toString(str2));//[全, 电话89和收集]

 

备注:因为String 实现了ChraSequence接口,所以直接可以用字符串

 

 

 

Pattern.matches
 /**
         * 快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串.
         *
         *  public static boolean matches(String regex, CharSequence input) {
         *         Pattern p = Pattern.compile(regex);
         *         Matcher m = p.matcher(input);
         *         return m.matches();
         *     }
         */

 

    Boolean re1 = Pattern.matches("\\d+","232");//true
        Boolean re2 = Pattern.matches("\\d+","23aa2");//false

 

 

Pattern类中的matcher方法
  /**
         *返回一个Macher对象
         *
         *因为Matcher的构造方法也是私有的 ,不能随意创建,
         * 只能通过下面方法创建了
         * public Matcher matcher(CharSequence input)
         */

 

        Pattern p3 = Pattern.compile("\\d+");
        Matcher matcher = p3.matcher("2321");
        System.out.println("p3"+matcher.pattern());//返回该Matcher对象是由哪个Pattern对象的创建的

 

Machter类

 

获得实例

  Pattern pattern1 = Pattern.compile("\\d+");
        /**
         * Matcher的构造方法也是私有的,只能通过pattern类中的matcher方法创建
         */
        Matcher matcher1 = pattern1.matcher("quan1zhi2qiang3hao4");

 

pattern()

/**
         * Matcher中的方法pattern()获取建立matcher实例时的pattern
         * 即构造器传入的Pattern对象。
         */
System.out.println(matcher1.pattern());//\d+

 

matches()

 /**
         * Matcher里面的matches方法,
         * 对整个字符串进行匹配,只有整个字符串都匹配了才返回true。
         */
  String mailstr = "1234@163.com";
        Pattern pattern = Pattern.compile("[\\w\\.]+@[\\w\\-\\.]+[\\w\\-]+");
        Matcher matcher = pattern.matcher(mailstr);
        System.out.println(matcher.matches());//true

 

lookAt()

/**
         * Matcher.lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true。
         *lookingAt是部分匹配,总是从第一个字符进行匹配,匹配成功了不再继续匹配,匹配失败了,也不继续匹配。
         */

 

String str1 = "123quan";
        String str2 = "quan123";
        Pattern pattern3 = Pattern.compile("\\d+");
        Matcher matcher3 = pattern3.matcher(str1);
        Matcher matcher4 = pattern3.matcher(str2);

        System.out.println(matcher3.lookingAt());//true
        System.out.println(matcher4.lookingAt());//false
        if(matcher4.find()){
            System.out.println(matcher4.group());//123
        }

 

 

find()

  /**
         * find()是部分匹配,从当前位置开始匹配,找到一个匹配的子串,将移动下次匹配的位置。
         *
         * 该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配
         * 的第一个字符开始。如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。
         */

 

        String str5 = "111quan222qq333";
        Pattern pattern5 = Pattern.compile("\\d+");
        Matcher matcher5 = pattern5.matcher(str5);
        while (matcher5.find()){
            System.out.println(matcher5.group());
        }
        /*
        111
        222
        333
         */

 

matches lookAt find联系

        /**
         * matches lookAt  find 的联系和区别;
         *都放回boolean类型:
         * 1,Matcher.matches()   对整个字符串进行匹配,只有整个字符串都匹配了才返回true
         * 2,Matcher.lookingAt()  从输入的头开始找,只有字符串的前缀满足模式才返回true
         * 3,Matcher.find()  对字符串进行匹配,匹配到的字符串可以在任何位置.
         */

 

   String str6 = "111quan222qq333";
        Pattern pattern6 = Pattern.compile("\\d+");
        Matcher matcher6 = pattern6.matcher(str6);
        matcher6.matches();//匹配在q这里失败了,下次匹配位置从位置4开始

        //下次匹配
        matcher6.find();
        System.out.println(matcher6.start());//查看这次匹配成功的开始位置
        //7

        matcher6.reset();//回到初始位置
        matcher6.lookingAt();
        System.out.println(matcher6.start());//查看这次匹配成功的开始位置
        //0

 

替换的三个方法:

 /**
         *replaceAll 替换符合所有Regex的部分
         * replaceFirst 替换第一个符合regex的部分
         * replace 用字符串替换字符串,没有匹配规则
         */

 

 String str7 = "111quan222qq333";
        Pattern pattern7 = Pattern.compile("\\d+");
        Matcher matcher7 = pattern6.matcher(str7);
        System.out.println(matcher7.replaceAll("@"));//@quan@qq@
        System.out.println(matcher7.replaceFirst("*"));//*quan222qq333
        //字符串里面也有替换函数
        System.out.println(str7.replace("111","BBB"));//BBBquan222qq333
        System.out.println(str7.replaceAll("\\d+","ALL"));//ALLquanALLqqALL
        System.out.println(str7.replaceFirst("\\d+","FIRST"));//FIRSTquan222qq333

 

 

正则表达式详解:

常用书写符号:

 

 

常用限定字符:

 

 

预定义字符集:

 

 

常用regex:

 

 

 

public class DemoRegex {
    public static void main(String[] args) {
        String qqstr = "12898878332";
        String qqreg = "[1-9]\\d{4,13}";//QQ没有0开头的
        Pattern pattern1 = Pattern.compile(qqreg);
        Matcher matcher = pattern1.matcher(qqstr);
        boolean re = matcher.matches();
        System.out.println(re);//true

        //按照叠词切割:其中\\1表示前面括号里面的组
        String[] strings = qqstr.split("(.)\\1+");
        System.out.println(Arrays.toString(strings));//[1289, 78, 2]

        
    }
}

http://www.51gjie.com/java/766.html

 

组:

A(B(C))D 有三个组:组 0 是 ABCD,组 1 是 BC,组 2 是 C,
可以根据有多少个左括号来来确定有多少个分组,括号里的表达式都称子表达式。

 

"(.)\\1+"

 

\\1就是反向引用

 

 

https://lilinchao.com/archives/339.html

推荐阅读