java中正则表达式的使用

java中正则表达式的使用

1.1. 简介

Regular Expression  正则表达式   常简称为: regex、正则

正则表达式是一整套约束字符串的语法规则,独立于任何编程语言

正则表达式 方便、灵活、功能强大,多部分编程语言都对正则表达式提供了支持

我们通常把正则作为一个工具,进行字符串的 校验、获取、替换等操作

 

应用场景:

校验用户输入的手机号是否符合要求

提取网页中的邮箱地址

将一段文本中所有的"李蛋"替换为"蛋蛋"

1.2. 普通字符和元字符 

正则表达式中,所有字符分为两类:普通字符和元字符(具有特殊含义的字符)

主要普通字符:小写字母、大写字母、数字、下划线、部分特殊符号、非西文字符等

主要元字符:.   \   { }  *   +   ?   ( )   [ ]   -   |   ^   $

 

.    表示任意一个字符(除了换行符)

\     转移符,用来改变其他字符的含义,

如:

\元字符 把元字符转义为普通字符,如\.  把元字符 . 转义为普通字符的 .

\普通字符 把普通字符转义为含有特殊含义的字符,如\n 换行符,\r 回车符,\t 制表符

1.3. Pattern

Java提供了java.util.regex.Pattern 类来创建正则表达式对象

 

public  static  boolean  matches(regex, str)  // 用来判断str是否匹配regex,或者说用来判断str是否符合regex的要求

 

例如:

boolean match = Pattern.matches("abc", "abcd");  //结果为false

这句代码解释:

正则要求字符串为"abc",但实际上字符串为"abcd",不符合正则的要求,所以不匹配,返回false

(注意:此方法要求严格,字符串必须完全符合正则要求才可以)

 

public class RegexTest {

 

    public static void main(String[] args) {

 

        String regex = "abc";// 要求字符串为"abc",str="abc"

        String str = "abc";

 

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

}

}


1.4. 元字符的用法

public class RegexTest {

 

    public static void main(String[] args) {

 

        //String regex = ".";// 要求str=任意一个字符

        //String str = "b5";

 

        String regex = "\\.";// \. 要求str="."

        String str = ".";

 

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

}

}

 

易错点:

1  Java代码中的 \\ 只表示正则中的 \

2  \n表示换行符,即使用\n这两个字符组合在一起表示一个换行字符

 

1.5. 重复匹配

(x表示一个字符,或者一个字符类,或者一个组等)

 

x{n}     x连续出现n

x{n,}    x至少连续出现n

x{n,m}  x至少连续出现n次,至多连续出现m

x*      x连续出现0次或多次,等同于x{0,}

x+      x至少连续出现1次,等同于x{1,}

x?      x出现0次或1次,等同于x{0,1}

 

public class RegexTest {

 

    public static void main(String[] args) {

 

        // String regex = "a{3}";// 要求a连续出现3次,str="aaa"

        // String str = "a";

 

        // String regex = "a{3,6}";// 要求a至少连续出现3次,str="aaa.."

        // String str = "aaaaaaa";

 

        String regex = "a?";

        String str = "a";

 

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

    }

}  


1.6. 选择匹配

使用 |  实现选择匹配,即多个选项中任选一个

a|b|c          匹配a或者b或者c

red|blue|green    匹配red或者blue或者green

 

public class RegexTest {

 

    public static void main(String[] args) {

 

        // String regex = "a|b|c";// str="a" "b" "c"

        // String str = "b";

 

        String regex = "red|blue|green";// str= "red" "blue" "green"

        String str = "gray";

 

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

    }    

}   

 

String regex = "[\\\\]"; 

反斜杠"\"在java中是一个转义字符,所以需要用两个代表一个,

"\"也是正则表达式中的转义字符,需要用两个代表一个。

"\\\\"被java转换成"\\","\\"又被正则表达式转换成"\",

因此用"[\\\\]"替换的时候,"\\\\"代表一个"\"。

String src = "\\";

反斜杠"\"在java中是一个转义字符,所以需要用两个代表一个,

"\\"代表一个"\"。

1.7. 字符类

字符类这个概念不易理解,只要记住它的用法就可以:匹配候选字符的任意一个

[ ]          [abc]   匹配abc中任意一个字符,类似 a|b|c

[^ ]        [^abc]   匹配非abc的任意一个字符

[ - ]        [0-9][a-z][a-zA-Z]   匹配范围内的任意一个字符

 

注意:字符类中的元字符(\除外),会被自动转义为普通字符,比如 [.]  等同于  [\.]

\w 代表一个单词字符,类似于[a-zA-Z0-9_],有的语言中也可以匹配中文

\W 代表一个非单词字符,类似于[^a-zA-Z0-9_]

\d 代表一个数字字符,等同于[0-9]

\D 代表一个非数字字符,等同于[^0-9]

\s 代表一个空白字符

\S 代表一个非空白字符

 

public class RegexTest {

 

    public static void main(String[] args) {

 

        // String regex = "hello[abc]";// str="helloa" "hellob" "helloc"

        // String str = "hellooa";

 

        // String regex = "[0-9]";// str="0" "1"..."9"

        // String str = "a";

 

        String regex = "\\w";// \w

        String str = "";

 

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

    }

}   


1.8. Matcher

Java还提供了 java.util.regex.Matcher  匹配器类,用来支持复杂的正则操作

Matcher matcher = Pattern.compile(regex).matcher(str);

boolean find = matcher.find();// 查找str中是否有下一个匹配regex的子字符串

String group = matcher.group();// 返回当前和regex匹配的子字符串

String subGroup = group(int group)//参数group表示的是当前和regex匹配的子字符串的第几组子字符串,0表示和当前regex匹配的子字符串整个子字符串,1表示与第一个组相匹配的字符串的内容,................要与组配合使用

例如:

                String regex = "(hel)lo";
String src2 = "asr hello, Hello helloa";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(src2);
while (matcher.find())
{
String src3 = matcher.group();
System.out.println(src3);

}

String src3 = matcher.group(0);//输出  hello 

String src3 = matcher.group(1);//输出  hel 

//典型用法

while (matcher.find()) {

       String substr = matcher.group();

       // ...

}

 

贪婪匹配:在重复匹配时,默认会匹配尽可能多的字符

非贪婪匹配:在重复匹配后面加上?问号,会匹配尽可能少的字符(并不严格)

 

public class RegexTest2 {

 

    public static void main(String[] args) {

 

        // String regex = "ab";// 要求str的子字符串substr="ab"

        // String str = "xabxxabmmabx";

 

        //打印出一个字符串里面的所有的qq邮箱

        String regex = "[1-9][0-9]{4,}@qq.com";// qq邮箱的正则表达式写法

        String str = "[email protected]@[email protected]";

 

        Pattern pattern = Pattern.compile(regex);

        Matcher matcher = pattern.matcher(str);

 

        while (matcher.find()) {

            String group = matcher.group();

            System.out.println(group);

        }

    }

}

 

 

 

1.9. String支持正则操作的方法

由于正则表达式和字符串如此相关,Java就为 java.lang.String 字符串类提供了若干可以直接进行正则操作的方法

 

//使用replacement替换全部匹配regex的子字符串

String newStr = str.replaceAll(regex, replacement);

String[] newStrs = str.split(regex);//使用regex作为分隔符切分str

boolean match = str.matches(regex);// 等同于Pattern.matches(regex, str)

 

public class RegexTest3 {

    public static void main(String[] args) {

        String str = "78ty4589jk78";

        // String newStr = str.replaceAll("[0-9]", "*");

        // System.out.println(newStr);

 

        // String[] parts = str.split("[0-9]+");

        // System.out.println(Arrays.toString(parts));

        System.out.println(str.matches("78ty4589jk78"));

    }

}


 

1.10. 位置匹配

正则中的匹配有两种,一种是匹配具体的字符,另一种是匹配特定的位置

^    匹配文本开始位置

$    匹配文本结束位置

\b   匹配单词边界(单词开始位置或结束位置)

 

校验操作时,是否使用 ^$ 对校验操作没有影响

获取、替换等操作时,一般不使用 ^$

 

public class RegexTest2 {

 

    public static void main(String[] args) {

 

        String regex = "\\bhello\\b";

        String str = "xx Hello,heLLo helloa ";

 

        Pattern pattern = Pattern.compile(regex);

        Matcher matcher = pattern.matcher(str);

 

        while (matcher.find()) {

            String group = matcher.group();

            System.out.println(group);

        }

    }

}


1.11. 

正则使用 ( ) 表示一个组,组可以让若干字符形成一个小整体

(ab)     匹配 ab

(red|blue|green)   匹配 red 或者 blue 或者 green

(red|blue|green) color   匹配 red color 或者 blue color 或者 green color

 

在匹配时,组的当前 "取值" 会被临时保存起来,方便引用。可以使用 \1 引用第一个组的当前"取值",最多可以引用九个不同的组:\9

(ab)c\1   匹配 abcab

([ab])\1   匹配 aa 或者 bb

(a)(b)\1\2   匹配 abab

 

public class RegexTest {

 

    public static void main(String[] args) {

 

        String regex = "(a)(b)\\1\\2";

        String str = "abab";

        

        boolean match = Pattern.matches(regex, str);

        System.out.println(match);

    }

}   


1.12. 标记flag

标记用来额外指定正则的匹配策略(标记可以不写在正则表达式内)

i         大小写不敏感  insensitive(也可以理解成ignore

g        全局匹配  global 效果是可以依次的获取到和正则匹配的所有子字符串

m       多行匹配  multiline 效果是^$可以匹配一段文本中每行的开始和结束位置

 

Java中:

在创建正则对象时可以通过 Pattern.compile(regex, flags)  指定标记

使用Pattern.CASE_INSENSITIVE 常量表示 i

使用Pattern.MULTILINE 常量表示 m

正则操作默认就是全局匹配的

 

public class RegexTest2 {

 

    public static void main(String[] args) {

 

        String regex = "\\bhello\\b";

        String str = "xx Hello,heLLo helloa ";

 

        // Pattern pattern = Pattern.compile(regex);

        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

        Matcher matcher = pattern.matcher(str);

 

        while (matcher.find()) {

            String group = matcher.group();

            System.out.println(group);

        }

    }

}

 


1.13. 常用正则

校验数字:^[0-9]*$

校验整数或者小数:^[0-9]+([.][0-9]+){0,1}$

校验qq号:[1-9][0-9]{4,}

校验手机号:  ^1[34578]\d{9}$

校验身份证:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|x|X)$)

校验日期(格式:yyyy-mm-dd,已考虑平闰年):^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

校验email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

校验URL^[a-zA-z]+://[^\s]*$

 

注意:以上常用正则并不保证完全满足需求,使用前请充分测试