Java正则表达式语法详解及使用案例

概述

  • 正则表达式通常用于判断某一个字符串是否符合或满足某一种格式,由一些具有特殊意义的字符构成,这些字符称为正则表达式的元字符
  • 正则表达式是文本处理中常用的工具,主要的应用包括匹配验证、分割、查找、替换

Java正则表达式中的元字符

元字符 意义
. 代表一个字符的通配符,能和回车符之外的任何字符相匹配
[] 字符集,能和括号内的任何一个字符相匹配。方括号内也可以表示一个范围,用“-”符号将起始和末尾字符区分开来, 例如[0-9]
[^] 排斥性字符集,和集合之外的任意字符匹配
^ 起始位置,定位到一行的起始处并向后匹配
$ 结束位置,定位到一行的结尾处并向前匹配
\b 单词边界
\B 非单词边界
() 按照子表达式进行分组
| 或关系的逻辑选择,通常和组结合使用
\ 用于转义,匹配反斜线符号之后的字符,所以可以匹配一些特殊符号
\d 数字,相当于[0-9]
\D 非数字,相当于[^0-9]
\s 空白符,相当于 [ \t\n\x0B\f\r]
\S 非空白符,相当于[^\s]
\w 单词字符,相当于[a-zA-Z_0-9]
\W 非单词字符,相当于[^\w]
\p{Lower} 表示小写字符a-z
\p{Upper} 表示大写字符A-Z
\p{ASCII} ASCII字符
\p{Alpha} 字母字符
\p{Digit} 数字0-9
\p{Alnum} 数字或字母
\p{Punct} 标点符号:!@#$%^&*()-_+=|[{}];:’"<>,.?/`~
\p{Graph} 可见字符[p{Alnum}\p{Punct}]
\p{Print} 可打印字符[\p{Graph}\x20]
\p{Blank} 空格或制表符[\t]
\p{Cntrl} 控制字符[\x00-\x1F\x7F]

正则表达式的元字符中有 “\”,编写正则表达式时需要变为"\",""[]"表示的一些其他格式:

  • [^123]:表示1、2、3之外的任何字符
  • [a-f]:表示a-f中任何一个字符
  • [a-zA-Z]:表示a-z或A-Z的任意字符
  • [a-o&&[def]]:表示a-o与d、e、f的交集
  • [a-d&&[^bc]]:表示字符a、d

正则表达式修饰符

限定修饰符 意义 示例
? 0次或1次 A?
* 0次或多次 A*
+ 1次或多次 A+
{n} 正好n次 A{2}
{n,} 至少n次 A{2,}
{n,m} 出现n-m次 A{2,4}

正则表达式语法及使用案例

1.Pattern类的用法

  • Pattern代表一个以字符串形式指定的正则表达式,表达式编译为Pattern对象,才能使用

  • static Pattern compile(String regex, int flags)

    regex是String形式的正则表达式,flags是模式类型,例如:DOTALL, CASE_INSENSITIVE, MULTILINE, UNICODE_CASE等,该方法返回一个Pattern的实例

  • Matcher matcher(CharSequence input)

    返回一个Matcher对象,表示创建给定字符串与正则表达式的匹配器,input为待匹配的字符串

  • static boolean matches(String regex, CharSequence input)

    第一个参数为正则表达式,第二个参数为待匹配字符串,表示编译给定的正则表达式并和待匹配字符串匹配

  • String[] split(CharSequence input)

    将输入字符串分割成字符串对象数组

public static void textSplit(){
		String info = "this is a simple exemple, let us see the effect .	Add some fruit: apple、 banana、tangerane";
		String reg = "[,.:、\\s]+";
//		[,.:、\\s]+匹配其中一种字符,可多次出现
		Pattern pat = Pattern.compile(reg);
		String []res = pat.split(info);
//		返回数组
		for(String s:res) {
			System.out.print(s+" ");
		}
 //		this is a simple exemple let us see the effect Add some fruit apple banana tangerane
}

2. Matcher类的用法

  • 需要Pattern对象的matcher方法才可以得到Matcher对象
public static void strReplace(){
//		替换字符串中的所有"-"	
		Pattern pattern = Pattern.compile("-");
		Matcher matcher = pattern.matcher("abcd-123a-4567-hdef");
//		删除所有的"-"
		String str = matcher.replaceAll("");
		System.out.println("替换后:"+str);
//		abcd123a4567hdef
}
  • boolean find()

    方法将扫描输入序列,寻找下一个与模式匹配的地方

  • Matcher appendReplacement(StringBuffer sb, String replacement)

    将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个 StringBuffer 对象里,替换时,$0表示整个匹配项,$1、$2…表示各个分组(圆括号)

  • StringBuffer appendTail(StringBuffer sb)

    将最后一次匹配工作后剩余的字符串添加到一个 StringBuffer 对象里

public static void strAppendReplace(){
		Pattern pattern = Pattern.compile("-");
		Matcher matcher = pattern.matcher("abcd-123a-4567-hdef");
		StringBuffer sb = new StringBuffer();
		while(matcher.find()) {
//       	$0表示整个匹配项
			matcher.appendReplacement(sb, "000$0");
		}
		matcher.appendTail(sb);
		System.out.println(sb.toString());
//		abcd000-123a000-4567000-hdef
}
  • String group(int group)

    group(分组)是指正则表达式中一对圆括号括起来的一部分,group(0)或group()表示整个匹配项,group(1)、group(2)…表示各个分组

//提取字符串中的年月日
public static void groupTest() {
		String regex = "([\\d]{2,4})[\\D]+([\\d]{1,2})[\\D]+([\\d]{1,2})";
		Pattern pat = Pattern.compile(regex);
	
		String []dd = {"1990-2-1","2000年11月23日","2020/7/18","1945 1 1"};
		for(String ss:dd) {
			Matcher mat = pat.matcher(ss);
		while(mat.find()) {
			String temp = mat.group();
//			String ss = mat.group(0);
			System.out.println("year:"+mat.group(1)); 
			System.out.println("month:"+mat.group(2));
			System.out.println("day:"+mat.group(3));
			System.out.println("RegxEmp.getBirth():"+temp);
		}
		}
	}

3. String对象的split方法

  • String[] split(String sign)

    根据给定的分隔符对字符串分隔,sign也可以采用正则表达式,定义多个分隔符,可使用”|“

  • String[] split(String sign,int limit)

    按分隔符分隔,并指定分隔次数

public static void stringSplit() {
		String ip = "192.168.1.1";
		String []arr = ip.split("\\.");
		for(String s:arr) {
			System.out.print(s+" ");
		}
		System.out.println();
		String []tt = ip.split("\\.",2);
		for(String s:tt) {
			System.out.print("分隔2次:"+s);
		}
		System.out.println();
		String txt = "this is a simple exemple, let us see the effect.";
//		",| |\\\\."表示分隔符分别根据","、"|"、" "、"."进行分隔    
		String []strs = txt.split(",| |\\.");
		for(String s:strs) {
			System.out.print(s+" ");
		}
/*		
		192 168 1 1 
		分隔2次:192分隔2次:168.1.1
		this is a simple exemple  let us see the effect 	
*/
	}

4.正则表达式使用案例

常见的一些正则表达式

  • 匹配邮箱:"\w+@\w+(\.\w{2,3})*\.\w{2,3}";

  • 匹配11位手机号:"[\d]{11}"

  • 匹配汉字:"[\u4e00-\u9fa5]"

  • 匹配英文状态下的标点符号:"[p{Punct}]+"

  • 匹配常见中文标点符号:"[ 。?!,、;:“”‘’()《》〈〉【 】『』「 」﹃ ﹄ 〔 〕 …—~ ﹏¥]"

4.1 正则式验证邮箱

//判断是不是符合邮箱的格式
public static boolean isEmail(String email) {
		String regex = "\\w+@\\w+(\\.\\w{2,3})*\\.\\w{2,3}";
		return email.matches(regex);
	}

4.2 验证手机号

public static void testPhone() {
		String regex = "[\\d]{11}";
		String number = "123456789012";
		boolean b = Pattern.matches(regex, number);
//		或用number.matches(regex)    
//		boolean b = number.matches(regex);
		System.out.println(b);
//		false    
	}

4.3 统计中文标点符号

	public static void testChineseChar() {
		String regex = "[ 。?!,、;:“”‘’()《》〈〉【 】『』「 」﹃ ﹄ 〔 〕 …—~ ﹏¥]";
		String info = "正则式测试: 冒号:句号。顿号、分号;括号(1,3)【标签】书名号《》‘’“”;、";
		Pattern pat = Pattern.compile(regex);
		Matcher mat =pat.matcher(info);
		int cnt = 0;
		while(mat.find()) {
			cnt++;
			System.out.print(cnt+"#"+mat.group()+" ");
		}
//		1#  2#: 3#。 4#、 5#; 6#( 7#, 8#) 9#【 10#】 11#《 12#》 13#‘ 14#’ 15#“ 16#” 17#; 18#、 
	}

4.4 正则式提取网页链接

//	链接内容提取
	public static void substringUrl() {
		ArrayList<String> info = new ArrayList<String>();
		info.add("测试1");
		info.add("测试2");
		info.add("测试3");
		info.add("");
		info.add("bbb ");
		String pat = "\\s+(href|src)\\s*=\\s*((\"[^\"]*\")|(\'[^\']*\')|([^\'\">]+))";
//		\\s+ 表示空白字符至少1个
//		(href|src) 匹配其中任意一个
//		(\"[^\"]*\") 匹配包含在""之间的字符,且中间不能出现 "
//		(\'[^\']*\') 匹配包含在' '之间的字符,且中间不能出现 '
//		([^\'\">]+) 不能出现 单引号 ',双引号 ",以及大于符号  >
//		((\"[^\"]*\")|(\'[^\']*\')|([^\'\">]+)) 匹配其中任意一组
//		不区分大小写匹配
		Pattern p = Pattern.compile(pat, Pattern.CASE_INSENSITIVE);
		for (int i = 0; i < info.size(); i++) {
//			匹配字符串
			Matcher mat = p.matcher(info.get(i));
//			find方法将扫描输入序列,寻找下一个与模式匹配的地方。 
			while (mat.find()) {
				System.out.println("emp" + i);
				System.out.println("0: " + mat.group());
//			mat.group(); 整个捕获,相当于goup(0)
				System.out.println("1: " + mat.group(1));
//			mat.group(1)捕获第1个括号 (href|src)
				System.out.println("2: " + mat.group(2));
				System.out.println();
//			mat.group(2)捕获第2个括号 ((\"[^\"]*\")|(\'[^\']*\')|([^\'\">]+))
			}
		}

	}

测试结果

emp0
0:  href = ' info.html '
1: href
2: ' info.html '

emp1
0:  href="info.html"
1: href
2: "info.html"

emp2
0:  href= "http://127.0.0.1:8848/JqueryTest/info.html  "
1: href
2: "http://127.0.0.1:8848/JqueryTest/info.html  "

emp3
0:  src = ""
1: src
2: ""

emp4
0:  href="http://aaa.htm"
1: href
2: "http://aaa.htm"

emp4
0:  src="http://bb.com/pic.jpg"
1: src
2: "http://bb.com/pic.jpg"

你可能感兴趣的:(Java)