Java正则表达式

如何匹配字符串?

如何判断字符串是否是有效的电话号码?

如何判断字符串是否是有效的电子邮件地址?

如何判断字符串是有效的时间?

从网页上爬取数据后如何判断哪些是图片资源?

那我们就开始学习正则表达式吧!

正则表达式可以用字符串来描述规则,并用来匹配字符串

  • 一个正则表达式就是一个描述规则的字符串
  • 只需要编写正确的规则,就可以让正则表达式引擎去判断目标字符串是否符合规则
  • 正则表达式是一套标准,可以用于任何语言
  • JDK内置正则表达式引擎:java.util.regex

我们来举个例子:判断用户输入的年份是否是19xx年

首先用户输入的规则是:

然后我们就可以编写出相应的正则表达式:1 9 \d \d (\d表示0-9的任意一个数字)

所有对应的Java字符串: "19\\d\\d" (java中\是转移字符所有我们要用两个反斜杠来表示一个反斜杠)

Java代码:

        String input = "1996";

        boolean matches = input.matches("19\\d\\d");
        if (matches){
            System.out.println("输入格式正确");
        }else {
            System.out.println("输入格式错误");
        }

正则表达式的匹配规则

  • 从左到右按规则匹配

如何编写正则表达式?

1、精确匹配:"abc"

表示精确的匹配"abc"这个字符串,并且大小写敏感,不能匹配"Abc"

        String input = "abcd";

        boolean matches = input.matches("abc");
        if (matches){
            System.out.println("输入格式正确");
        }else {
            System.out.println("输入格式错误");
        }
//输入格式错误
//如果  String input = "abc"; 则输入格式正确

2、精确匹配:"a\&c",特殊字符需要转义

3、特殊符号 . 可以匹配一个任意字符 : "a.c"

        String input = "a和c";

        boolean matches = input.matches("a.c");
        if (matches){
            System.out.println("输入格式正确");
        }else {
            System.out.println("输入格式错误");
        }
    }
//格式正确
//”ac“ 和 "abbc" 是不会匹配成功的

4、符号\d可以匹配一个数字:"00\d"

        String input = "009";

        boolean matches = input.matches("00\\d");
//"009" 匹配成功
//"00A"和"0088"是不会匹配成功的

5、符号\w可以匹配一个字母、数字或下划线: "java\w"

        String input = "java_";

        boolean matches = input.matches("java\\w");
//"java_" 匹配成功
//"java#" 和 "java "是不会匹配成功的

6、符号\s可以匹配一个空白字符 : "A\sB"

        String input = "A B";

        boolean matches = input.matches("A\\sB");
// B"匹配成功
//	B" 可以匹配成功  tab键也算空白字符
//B"  和 "A       B"   不行 

7、符号\D可以匹配一个非数字: "00\D"

        String input = "00A";

        boolean matches = input.matches("00\\D");

//"00A" 匹配成功
//"001" 和 "004" 不行

8、符号\W可以匹配一个非字母、数字或下划线: "java\W"

        String input = "java!";

        boolean matches = input.matches("java\\W");

//"java!" 匹配成功
//"java2" 、 "Javaa" 和 "java_" 不行

9、符号\S可以匹配一个非空白字符

        String input = "ABB";

        boolean matches = input.matches("A\\SB");
//"A&B" 也可以成功
//"A B" 和 "A	B" 不行  tab键也算空白键    

10、修饰符*可以匹配任意个字符: "A\d*"

        String input = "A4674";

        boolean matches = input.matches("A\\d*");
// "A" , "A1" 和 "A876" 都可以
// "AH" 不行

11、修饰符+可以匹配至少一个字符:"A\d+"

        String input = "A4674";

        boolean matches = input.matches("A\\d+");
//"A4674"
//"A"  、 "AV"  不可以

12、修饰符?可以匹配零个或者一个字符: "A\d?"

        String input = "A4";

        boolean matches = input.matches("A\\d?");
// "A"  "A1" 可以
// "A12"  "Ab" 不可以

13、修饰符{n}可以匹配n个字符: "\d{6}"

        String input = "345325";

        boolean matches = input.matches("\\d{6}");
//"123456"  "111111"  可以
//"1234"  "12345a"  不行

14、修饰符{n,m}可以匹配n-m个字符:"\d{3,5}"

        String input = "34532";

        boolean matches = input.matches("\\d{3,5}");
//"123"  "12345"  可以
//"123456"  "1234A" 不行

15、修饰符{n,}可以匹配至少n个字符:"\d{3,}"

        String input = "123";

        boolean matches = input.matches("\\d{3,}");
//"123" "12345" "1234567"  可以
//"12"  "12A" 不行

我们给简单匹配规则做个小总结

正则表达式 规则 可以匹配
A 指定字符 A
. 任意字符 a,c,d,&,4
\d 0-9 0,1,2,3.....9
\w a-z,A-Z,1-9,_ a,A,2,_......
\s 空格,Tab键 " "
\D 非数字 a,A,&,_......
\W 非\w &^%$...
\S 非\s a,A,%,_

我们再来看看复杂一点的匹配规则

1、和$匹配开始和结尾:"A\d{3}$"

        String input = "A001";

        boolean matches = input.matches("^A\\d{3}$");

//"A001"  "A777"   可以
//"B001"  "B0001"  不行

2、[...]可以匹配范围内的字符:"[abc]1" 只能匹配某一个字符

        String input = "A001";

        boolean matches = input.matches("[abc]1");
//"a1"  "b1"  "c1" 可以
//"ab1"  "x1"  不行

3、[...] 可以匹配范围内的字符:"[a-f]1"

        String input = "d1"; 

        boolean matches = input.matches("[a-f]1");
//"a1" "b1" "f1"可以
//"r1"  "ab1"  不行

4、[...] 可以匹配范围内的字符:"[a-f0-9]{6}}"

        String input = "433abc";

        boolean matches = input.matches("[a-f0-9]{6}");
//"1a2b4c"  "ffffff"  "111111" 可以
//"agc2"  "ad222F"  不行 F大写不在a-f范围内

//还可以写成 boolean matches = input.matches("[a-f0-9_]{6}");
//那就还可以匹配_

5、[^] 可以匹配非范围内的字符:"[ ^ 0-9]"

        String input = "asdfgh";

        boolean matches = input.matches("[^0-9]{6}");
//"asdfgh"  "$$$$$$" "a-b-c"  可以
//"123456"  "ads23f"  不可以

6、AB|CD 可以匹配AB或CD : "java|go"

        String input = "java";

        boolean matches = input.matches("java|go");
//"java"  "go"  可以
//"c++"  "javago" 不行

//再举个例子
boolean matches = input.matches("love\\s(java|go)");

//"love java" "love go" 可以
//"love c++" "love python" 不可以

我们来做个小总结

正则表达式 规则 可以匹配
^ 开头 字符串开头
$ 结尾 字符串结尾
[ABC] [...]内任意字符 A,B,C
[a-f0-9xy] 指定范围的字符 a,2,x,y
[^A-F] 指定范围外的任意字符 非A....F
AB|CD AB或CD AB,CD
AB|CD|EF AB或CD或EF AB,CD,EF

再来说一说分组匹配规则

1、(...)可以分组:(\d{4}\-\d{1,2}\-(\d{1,2}))

        String input = "2020-11-22";

        boolean matches = input.matches("(\\d{4}\\-(\\d{1,2})\\-(\\d{1,2}))");

//"2020-11-22" 可以

我们再来举个例子,提取电话号码

-########

^ \d{3,4} \- \d{6,8} $

^ :开头

\d{3,4}:3-4位区号

\- : 符号"-"

\d{6,8}:6-8位电话号码

$ 结束

        String input = "010-1234567";

        boolean matches = input.matches("^(\\d{3,4})\\-(\\d{6,8})$");
//"010-1234567"可以

反复使用一个正则表达式字符串进行快速匹配效率较低(方法内部实际上是调用了Pattern对象)

我们可以把正则表达式编译为Pattern对象,然后反复使用他,就可以实现一次编译多次匹配

        Pattern pattern = Pattern.compile("^(\\d{3,4})\\-(\\d{6,8})$");

        boolean matches = pattern.matcher("010-1234567").matches();

        if (matches){
            System.out.println("输入格式正确");
        }else {
            System.out.println("输入格式错误");
        }

**使用Matcher.group(n)可以快速提取子串 ** 一个()代表一个子串

        Pattern pattern = Pattern.compile("^(\\d{3,4})\\-(\\d{6,8})$");

        Matcher matcher = pattern.matcher("010-1234567");

        if (matcher.matches()){
            String whole = matcher.group(0);  //"010-1234567"  0表示匹配整个字符串
            String areaCode = matcher.group(1);  //"010" ,1表示匹配第一个字符串
            String telNumber = matcher.group(2); //"1234567",表示匹配的第二个字符串
        }
非贪婪匹配

正则表达式默认使用贪婪匹配

  • 尽可能多的向后匹配

  • 使用?实现非贪婪匹配

搜索和替换

使用正则表达式分割字符串

  • String[] String.split(String regex)

            String[] split = "a b c".split("\\s");//["a", "b", "c"]
     	    String[] split = "a b  c".split("\\s");//["a", "b","", "c"]
     	    String[] split = "a b  c".split("\\s+");//["a", "b","c"]
     	    String[] split = "a, b;;  c".split("\\,\\;\\s+");//["a", "b","c"]
    

使用正则表达式搜索字符串

  • Matcher.find()
        String str = "I love you";

        Pattern pattern = Pattern.compile("love");

        Matcher matcher = pattern.matcher(str);

        while (matcher.find()){
            String substring = str.substring(matcher.start(), matcher.end());
            System.out.println(substring);
        }

使用正则表达式替换字符串

  • String.replaceAll()

            String str = "I love you";
    
            String all = str.replaceAll("\\s+", ""); //Iloveyou
    
    
posted @ 2020-11-22 19:04  吕敬瑛  阅读(955)  评论(2编辑  收藏  举报