Java正则表达式

一、普通字符

普通字符包括以下类别:
1. a-z A-Z 0-9 !#@~等 非特殊含义字符
2. 反斜杠 \:第一个斜杠表示转义,第二个斜杠才是表示”\”字符,由于在java中表示”\”也需要转义,所以在java中是用正则表达式表示一个”\”需要写成”\\”
3. \t 制表符:由于”\t”在java中也表示制表符,所以可以直接使用”\t”,而使用”\t”的时候其中一个”\”代表转义,剩下来的”\t”在正则中正好表示制表符所以它们的效果一样
4. \n 换行符:同上
5. \f 换页符:同上
例子程序:

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * @GITHUB: https://github.com/sahooz
 * @CSDN: http://blog.csdn.net/u013028621
 */
public class NormalCharacter {
    private static final String TARGET = "abcdefgHIJKLMN0123456789!#@~\\\t\n\f";

    public static void main(String[] args) {
        test1();
        test2();
        test3();
    }

    /**
     * 测试第三类
     */
    private static void test3() {
        System.out.println("斜杠t的匹配结果:");
        Pattern pattern = Pattern.compile("\t");
        Matcher matcher = pattern.matcher(TARGET);
        System.out.println(matcher.find());
        System.out.println("双斜杠t的匹配结果:");
        pattern = Pattern.compile("\\t");
        matcher = pattern.matcher(TARGET);
        System.out.println(matcher.find());
    }
    /**
     * 测试第二类:"\"
     */
    private static void test2() {
        try {
            System.out.println("双斜杠的匹配结果:");
            Pattern pattern = Pattern.compile("\\"); //会报错,因为经过java转义表示正则里的"\",而正则里的"\"不能单独使用
            Matcher matcher = pattern.matcher(TARGET);
            if(matcher.find())
                System.out.println(matcher.group());
        } catch (Exception e) {
            System.out.println("抛出异常!!");
        }
        System.out.println("四斜杠的匹配结果:");
        Pattern pattern = Pattern.compile("\\\\"); 
        Matcher matcher = pattern.matcher(TARGET);
        if(matcher.find())
            System.out.println(matcher.group());
    }
    /**
     * 测试第一类
     */
    private static void test1() {
        char[] charArray = TARGET.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
            if(c != '\\' && c != '\t' && c != '\n' && c != '\f') {
                Pattern pattern = Pattern.compile(c + "");
                Matcher matcher = pattern.matcher(TARGET);
                if(matcher.find())
                    System.out.print(matcher.group());
            }
        }
        System.out.println();
    }
}

运行结果:
这里写图片描述

二、字符类

字符类相对于普通字符的区别是,它表示的是满足特定条件的一类字符中的一个,主要有以下类别:
1.[abc]: a、b 或 c(简单类)
2.[^abc]: 任何字符,除了 a、b 或 c(否定)
3.[a-zA-Z]: a 到 z 或 A 到 Z,两头的字母包括在内(范围)
4.[a-d[m-p]]: a 到 d 或 m 到 p:[a-dm-p](并集)
5.[a-z&&[def]]: d、e 或 f(交集)
6.[a-z&&[^bc]]: a 到 z,除了 b 和 c:[ad-z](减去)
7.[a-z&&[^m-p]]: a 到 z,而非 m 到 p:[a-lq-z](减去)

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** 
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class CharacterClasses {
    private static final String TARGET = "abcdefgHIJKLMN0123456789!#@~.";

    public static void main(String[] args) {
        System.out.print("所有属于IJK之中某一个的字符:");
        print("[IJK]");
        System.out.print("所有不属于IJK之中某一个的字符:");
        print("[^IJK]");
        System.out.print("所有属于b到g之中某一个的字符:");
        print("[b-g]");
        System.out.print("所有属于b到g或K到N之中某一个的字符:");
        print("[b-g[K-N]]");
        System.out.print("所有属于b到g或K到N之中某一个的字符:");
        print("[b-gK-N]");
        System.out.print("所有属于b到g且属于e到z之中某一个的字符:");
        print("[b-g&&e-z]");
        System.out.print("所有属于b到g且不属于e到z之中某一个的字符:");
        print("[b-g&&[^e-z]]");
    }
    private static void print(String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.print(matcher.group());
        System.out.println();
    }
}

运行结果:
这里写图片描述

三、预定义字符类

特殊字符有:
1). 通配符,可以表示除换行符以外任意字符(换行符可能匹配,可能不匹配),匹配”.”本身需要使用”.”,
由于在java中”\”需要转义,所以写成”\.”,下同
2)\d 数字字符,[0-9]
3)\D 非数字字符,[^0-9]
4)\w 单词字符,[a-zA-Z_0-9]
5)\W 非单词字符,[^a-zA-Z_0-9]
6)\s 空白字符:[\t\n\x0B\f\r]
7)\S 非空白字符:[^\s]
例子程序:

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class SpecialCharacter {
    private static final String TARGET = "abcdefgHIJKLMN0123456789!#@~.^_\\s\\S\\w\\W\\d\\D\t\n";

    public static void main(String[] args) {
        System.out.println("目标字符串: " + TARGET);
        System.out.print("与通配符.匹配的所有字符:");
        print(".");
        System.out.print("匹配.字符本身:");
        print("\\.");
        System.out.print("匹配所有数字字符:");
        print("\\d");
        System.out.print("匹配所有非数字字符:");
        print("\\D");
        System.out.print("匹配所有单词字符:");
        print("\\w");
        System.out.print("匹配所有非单词字符:");
        print("\\W");
        System.out.print("匹配所有的字符:");
        print("[\\w\\W]");//同理可以使用"[\\s\\S]"
    }

    private static void print(String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.print(matcher.group());
        System.out.println();
    }
}

运行结果:
这里写图片描述
其中空白处其实包含了换行符制表符等。

四、匹配模式与边界匹配器

匹配模式:
1.单行模式(DOTALL): 整个文本视为一个字符串(一行),.能匹配所有字符的模式
2.多行模式(MULTILINE): 整个文本视为以换行符分隔的多行文本
3.大小写敏感模式: 大小写字母视为不一样的字符,比如a不能匹配到A
4.大小写不敏感模式(CASE_INSENSITIVE): 大小写字母视为一样的字符,比如a能匹配到A
默认模式为单行大小写敏感
边界匹配器:不代表任何字符,只表示目标字符(字符串)应该符合某个位置条件
1.^ 行的开头,单行模式下类似于\A
2.$ 行的结尾 ,单行模式下类似于\Z
3.\b 单词边界,也就是单词开始或结束的位置
4.\B 非单词边界,非\b位置
5.\A 输入的开头 ,无论单行多行模式
6.\Z 输入的结尾
例子程序:

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class BoundaryMatchers {

    private static final String TARGET = "Weak mind.\n" +
            "Weak willpower.\n" +
            "What is next?\n" +
            "You cannot positively influence your life when you are not emotionally strong. Strength comes from within.\n" +
            "Regardless of who your parents are and how much your husband earns, you cannot be a strong woman until you learn how to manage your emotions\n";
    public static void main(String[] args) {
        System.out.print("单行模式下^W(位于行开始位置的所有\"W\"字符)匹配的所有字符:");
        print("^W", Pattern.DOTALL);
        System.out.print("多行模式下^W(位于行开始位置的所有\"W\"字符)匹配的所有字符:");
        print("^W", Pattern.MULTILINE);
        System.out.print("多行模式下.$(位于行结束位置的所有字符)匹配的所有字符:");
        print(".$", Pattern.MULTILINE);
        System.out.print("多行模式下\\A.(整个输入的第一个能被\".\"匹配的字符)匹配的所有字符:");
        print("\\AW", Pattern.MULTILINE);
        System.out.print("单行模式下\\A.(整个输入的第一个能被\".\"匹配的字符)匹配的所有字符:");
        print("\\AW", Pattern.DOTALL);
        System.out.print(".\\Z(整个输入的结尾)匹配的所有字符:");
        print(".\\Z", 0/*默认*/);
        System.out.print(".\\b(位于单词边界的前一个字母)匹配的所有字符:");
        print("[a-zA-Z]\\b", 0);        
    }

    private static void print(String regex, int mode) {
        Pattern pattern = Pattern.compile(regex, mode);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.print(matcher.group());
        System.out.println();
    }
}

运行结果:
这里写图片描述

五、量词与匹配模式

量词与匹配模式(贪婪模式、勉强模式)
贪婪模式: 趋向于最大长度匹配
勉强模式: 趋向于最小长度匹配
贪婪模式量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
勉强模式量词
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
例子程序:

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class Quantifiers {
    private static final String TARGET = "abcdefgHIJKLMN0123456789!#@~.";

    public static void main(String[] args) {
        System.out.println("贪婪模式下[a-zA-Z]{3,5}的匹配结果(所有由3到5个字母组成的子序列):");
        print("[a-zA-Z]{3,5}");
        System.out.println("勉强模式下[a-zA-Z]{3,5}的匹配结果(所有由3到5个字母组成的子序列):");
        print("[a-zA-Z]{3,5}?");
    }
    private static void print(String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.println(matcher.group());
    }
}

运行结果:
这里写图片描述
可以看到,贪婪模式下每次匹配都是尽量选择满足条件的最长的子序列,在不够的情况下,才会匹配较短的序列;在勉强匹配下,匹配的是满足条件的最短的子序列。

六、捕获组

捕获组:用小括号括起来的一个匹配规则为一个捕获组,例如([a-z][0-9])+表示由一个或以上”a到z之间的字母与0到9之间的数字组合”组成的子序列。捕获组按照左边的小括号从1开始进行排序,每个捕获组最后一个匹配结果可以通过Matcher.group(int),没有匹配的时候返回的是null.0代表正则表达式整体的匹配结果,与Matcher.group()等效.
例子程序:

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class CaptureGroup {

    private static final String TARGET = "a0b1c2d3aabbccdde4f5";

    public static void main(String[] args) {

        //下面只有一个捕获组
        Pattern p = Pattern.compile("([a-z][0-9])+[a-z]{2}");
        Matcher m = p.matcher(TARGET);
        while(m.find()){
            for(int i = 0; i<= m.groupCount(); i++)
                System.out.println(m.group(i));
        }
        System.out.println("=======分割线=======");
        //看起好像一样,但是下面是两个捕获组
        p = Pattern.compile("([a-z][0-9])+([a-z]){2}");
        m = p.matcher(TARGET);
        while(m.find()){
            for(int i = 0; i<= m.groupCount(); i++)
                System.out.println(m.group(i));
        }
    }
}

运行结果:
这里写图片描述

七、非捕获组

非捕获组,用于正则表达式匹配规则但不计入最终匹配结果
1.(?=X ) 零宽度正先行断言。仅当子表达式 X在此位置的右侧匹配时才继续匹配。例如,\w+(?=A)表示位于A前面的由一个以上单词字符组成的子序列,但不包括后面的这个A
2.(?!X) 零宽度负先行断言。仅当子表达式 X不在此位置的右侧匹配时才继续匹配。例如,例如,\w+(?!\A)表示不位于A前面的由一个以上单词字符组成的子序列,但不包括后面的这个A
3.(?<=X) 零宽度正后发断言。仅当子表达式 X在此位置的左侧匹配时才继续匹配。例如,(?<=A)99 与跟在 A后面的99的实例匹配
4.(?

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class NonCapturing {
    private static final String TARGET = "abcdAabcd$99A99";

    public static void main(String[] args) {
        System.out.println("位于A前面的由一个以上单词字符组成的子序列");
        print("\\w+(?=A)");
        System.out.println("不位于A前面的由两个以上字母组成的子序列");
        print("[a-zA-Z]{2,}(?!=A)");
        System.out.println("跟在 A后面的99");
        print("(?<=A)99");
        System.out.println("不跟在 A后面的99");
        print("(?<!A)99");
    }

    private static void print(String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.print(matcher.group());
        System.out.println();
    }
}

运行结果:
这里写图片描述

八、反向引用

反向引用: 引用前一个捕获组的匹配结果,形式为\x,x代表捕获组的序号,比如([a-z])\1表示相同的两个小写字母组成的子序列,比如aa,bb,cc等
例子程序

package com.sahooz.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author sahooz
 * github: https://github.com/sahooz
 * CSDN: http://blog.csdn.net/u013028621
 */
public class BackReferences {

    private static final String TARGET = "aabbccdd";

    public static void main(String[] args) {
        print("([a-z])\\1");
    }

    private static void print(String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(TARGET);
        while(matcher.find())
            System.out.println(matcher.group());
    }
}

运行结果:
这里写图片描述

代码

github: https://github.com/sahooz/JavaRegexDemo
CSDN: http://download.csdn.net/download/u013028621/10143506

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值