java之正则表达式的使用学习笔记(完整)

java之正则表达式的使用

正则表达式

  1. 匹配规则

    正则表达式的匹配规则就是从左到右按规则匹配

    • 匹配任意字符

      // 在正则表达式中,'.'表示匹配任意一个字符
      public class Regex{
      	public static void main(String[] argc){
      		String s = "cde";
      		boolean f = s.matches("c.e");
      		System.out.println(f); //true
      	}	
      }
      
    • 匹配数字

      // 	在正则表达式中,'\d'可以匹配单个数字字符
      // 因为正则在java中也是作为字符串,所以使用时要用'\\d',需要对\进行转义
      public class Regex{
      	public static void main(String[] argc){
      		String s = "cde8";
      		boolean f = s.matches("c.e\\d");
      		System.out.println(f); //true
      	}	
      }
      
    • 匹配常用字符

      // 在正则表达式中,'\w'可以匹配一个字母、数字或者下划线,w(word),除此之外不能匹配任何字符,像#、空格……
      public class Regex{
      	public static void main(String[] argc){
      		String s = "cde8";
      		boolean f = s.matches("c\\we\\w");
      		System.out.println(f); //true
      	}	
      }
      
    • 匹配空格字符

      // 在正则表达式中,'\s'可以匹配一个空格字符,包括tab(\t)
      public class Regex{
      	public static void main(String[] argc){
      		String s = "c	de 8";
      		boolean f = s.matches("c\\s\\we\\s\\d");
      		System.out.println(f); //true
      	}
      }
      
    • 匹配非数字

      // '\d'可以匹配一个数字,'\D'则匹配一个非数字
      // 相应的 '\W' 可以匹配 '\w' 不能匹配的字符
      // '\S' 可以匹配 '\s' 不能匹配的字符
      
    • 重复匹配

      // 修饰符 * 可以匹配任意个字符,包括0个
      // 'A\d*' 可以匹配 'A' 'A0' 'A380'
      // 修饰符 + 可以匹配至少一个字符
      // 'A\d+' 可以匹配 'A0' 'A380'
      // 修饰符 ? 可以匹配0个或者1个字符
      // 'A\d?' 可以匹配 'A' 'A0'
      //如果想精确指定n个字符,使用修饰符{n}
      //例如 '\d{3}'可以匹配三个数字
      // 使用{n,m}可以制定匹配n~m个字符,没有上限,使用{n,}
      
    • 案例:使用正则匹配国内电话号码规则:34位区号加78位电话,中间用 - 连接

      import java.util.Scanner;
      public class Regex{
      	public static void main(String[] argc){
      		Scanner scan = new Scanner(System.in);
      		String s = scan.next();
      		scan.close();
      		System.out.println(s.matches("\\d{3,4}-\\d{7,8}"));
      	}	
      }
      
  2. 复杂匹配规则

    • 匹配开头和结尾

      // 使用正则表达式进行多行匹配时,使用 ^ 表示开头,使用 $ 表示结尾
      // 例如 '^A\d{3}$' 表示以A开头,以三个数字结尾
      
    • 匹配指定范围

      // 正则表达式使用 [] 进行范围匹配
      // 例如 '[1-9]\d{6,7}'
      // 要匹配大小写不限的十六进制数,比如 1A2b3c 使用[0-9a-fA-F]
      // 如果要匹配 6 位十六进制数,则[0-9a-fA-F]{6}即可
      
    • 进阶案例:电话号码匹配规则中区号以0开头,号码不能以0开头

      import java.util.Scanner;
      public class Regex{
      	public static void main(String[] argc){
      		Scanner scan = new Scanner(System.in);
      		String s = scan.next();
      		scan.close();
      		System.out.println(s.matches("^0\\d{2,3}-[1-9]\\d{6,7}"));
      	}	
      }
      
    • 或规则匹配

      // 使用 | 连接两个正则规则 例如AB|CD 匹配AB或者CD
      // 当匹配多个字符串,且字符串具有公共部分时,可以提取公共部分,使用小括号括起来非公共部分
      // learn\s(java|php|go) 有点类似分配率
      
  3. 分组匹配

    • 使用 (…) 进行分组

      // 例如 (\d{3,4})-(\d{6,8})
      
    • 提取字符串

      import java.util.Scanner;
      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		Scanner scan = new Scanner(System.in);
      		String s = scan.next();
      		scan.close();
      		Pattern p = Pattern.compile("(^0\\d{2,3})-([1-9]\\d{6,7})");
      		Matcher m = p.matcher(s);
      		if(m.matches()){
      			String g1 = m.group(1);
      			String g2 = m.group(2);
      			System.out.print(g1 + "  " + g2);
      		}else{
      			System.out.print("匹配失败");
      		}
      	}	
      }
      //输入:010-1000000
      //输出:010  1000000
      

      注:Matcher.group(index) 参数 1 表示第一个字符串, 2 表示第二个字符串,0表示原来的字符串

    • 使用Pattern

      //前面用到的String.matches(String regex)内部调用的还是Pattern 和
      //Matcher类中的方法,当需要多次进行匹配时,每次都会创建不同的Pattern
      //对象,因此效率较低,因此可以创建Pattern对象,创建一次可以多次进行匹配
      import java.util.Scanner;
      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		Scanner scan = new Scanner(System.in);
      		String s = scan.next();
      		scan.close();
      		Pattern p = Pattern.compile("(^0\\d{2,3})-([1-9]\\d{6,7})");
      		Matcher m = p.matcher(s);
              //可以使用Pattern的实例 p 匹配更多地字符串
              //p.matcher(String s)
      		if(m.matches()){
      			String g1 = m.group(1);
      			String g2 = m.group(2);
      			System.out.print(g1 + "  " + g2);
      		}else{
      			System.out.print("匹配失败");
      		}
      	}	
      }
      

      注:使用Matcher类中的方法时,必须先判断是否匹配成功,及调用Matcher.matches()方法

    • 练习:从字符串 “23:01:59” 提取时分秒

      import java.util.Scanner;
      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		Scanner scan = new Scanner(System.in);
      		String s = scan.next();
      		scan.close();
      		Pattern pattern = Pattern.compile("([0-2][0-9]):([0-5][0-9]):([0-5][0-9])");
      		Matcher m = pattern.matcher(s);
      		if(m.matches()){
      			String time = m.group(0);
      			String hour = m.group(1);
      			String minute = m.group(2);
      			String second = m.group(3);
      			System.out.println("时间:" + time);
      			System.out.println("小时:" + Integer.parseInt(hour) + "  分钟:" + Integer.parseInt(minute) + "  秒:" + Integer.parseInt(second));
      		}else{
      			System.out.println("匹配失败");
      		}
      	}	
      }
      //输入 :23:01:05
      //时间:23:01:05
      //小时:23  分钟:1  秒:5
      
  4. 非贪婪匹配

    • 贪婪匹配

      正则表达式默认使用贪婪匹配,即任何一个规则,它总是尽可能多的向后匹配

    • 非贪婪匹配

      在规则的后面加上 ? 即可表示非贪婪匹配

      //下面的代码用来判断一串数字末尾0的个数
      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		Pattern pattern = Pattern.compile("(\\d+?)(0*)");
      		Matcher m = pattern.matcher("012000");
      		Matcher m1 = pattern.matcher("1200100000");
      		Matcher m2 = pattern.matcher("01000");
      		Matcher m3 = pattern.matcher("0001");
      		if(m1.matches() && m2.matches() && m3.matches() && m.matches()){
      			String g = m.group(2);
      			String g1 = m1.group(2);
      			String g2 = m2.group(2);
      			String g3 = m3.group(2);
      			System.out.println(m.group(0)+"末尾有" + g.length() + "个零");
      			System.out.println(m1.group(0)+"末尾有" + g1.length() + "个零");
      			System.out.println(m2.group(0)+"末尾有" + g2.length() + "个零");
      			System.out.println(m3.group(0)+"末尾有" + g3.length() + "个零");
      		}else{
      				System.out.print("匹配失败");
      		}
      	}
      }
      
  5. 搜索和替换

    • 字符串分割

      使用 String.split(String regex);

      "a, b ;; c".split("[\\,\\;\\s]+");
      
    • 搜索字符串

      我们获取Matcher对象时,不需要调用matcher方法,因为对整个字符串返回肯定是false,因此需要反复调用find方法,在整个串上匹配正则

      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		String s = "the quick brown fox jumps over the lazy dog";
      		Pattern pattern = Pattern.compile("\\wo\\w");
      		Matcher m = pattern.matcher(s);
      		while(m.find()){
      			String sub = s.substring(m.start(), m.end());
      			System.out.println(sub);
      		}
      	}
      }
      //输出:
      //		row
      //		fox
      //		dog
      
    • 替换字符串

      使用正则表达式替换字符串可以直接调用String.replaceAll(String regex, String s)

      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		String s = "the \t\t quick    brown   fox  jumps over  the   \t lazy dog";
      		String ns = s.replaceAll("\\s+", " ");
      		System.out.println(ns);
      	}
      }
      
    • 反向引用

      即将匹配到的字符串作为引用来使用,使用$1、$2来反向引用匹配到的子串

      import java.util.regex.*;
      public class Regex{
      	public static void main(String[] argc){
      		String s = "the quick brown fox jumps over the lazy dog.";
              String r = s.replaceAll("\\s([a-z]{4})\\s", " $ ");
              System.out.println(r);
      	}
      }
      
  • 总结来说,正则表达式在任何编程语言中都是适用的,而且在判断一些字符串是否符合某种规范的时候特别方便,就是记忆的内容比较多,但是相对来说还是很好理解的,不需要怎么记,只需要明白每一种规则的使用即可,重点是如何灵活组合正则表达式来达到某种要求,因此需要多练习

你可能感兴趣的:(正则表达式,java,后端)