Skip to content

Java正则表达式使用

小傅哥 edited this page May 20, 2020 · 1 revision

案例

//汉字范围u4E00-u9FA5
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class sxtRegex01 {
	
	public static void main(String[] args) {
		
		p("检查是否匹配:"+"abc".matches("..."));
		
		p("替换字符串:"+"abc123aa".replaceAll("\\d", "."));
		
		Pattern p = Pattern.compile("[a-z]{3}");
		Matcher m = p.matcher("fgha");
		p("Pattern+Matcher方法验证匹配:"+m.matches());
		
		p("------------------");
		
		p("a".matches("[abc]"));
		p("a".matches("[^abc]"));
		p("A".matches("[a-zA-Z]"));
		p("A".matches("[a-z]|[A-Z]"));
		p("A".matches("[a-z(A-Z)]"));
		p("R".matches("[A-Z&&(RFG)]"));
		
		p("------------------");
		
		p("a_8".matches("\\w{3}"));
		p("\\".matches("\\\\"));
		
		p("------------------");
		
		p("hello sir".matches("h.*"));
		p("hello sir".matches(".*ir$"));
		p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//匹配单词边界,单词边界是空格出现的位置用\\b匹配
		p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));
		p(" \n".matches("^[\\s&&[^\\n]]*\\n$"));//开头是一个空格,且不能是换行符,最后必须是换行
	    
		p("------------------");
		
		Pattern p2 = Pattern.compile("\\d{3,5}");
		String s = "123-4536-89789-000";
		Matcher m2 = p2.matcher(s);
		
		p(m2.matches());
		m2.reset();//把吃进去的字符吐出来重新匹配,否经过m2.matches会吃进去字符 下面的匹配就不成功
		p(m2.find());
		p(m2.start()+"-"+m2.end());//找到了 就把首位位置打印下(必须找到才能打印)
		p(m2.find());
		p(m2.start()+"-"+m2.end());
		p(m2.find());
		p(m2.start()+"-"+m2.end());
		p(m2.find());
		
		p(m2.lookingAt());//每次都是才头上开始找
		
		p("------------------");
		
		Pattern p3 = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//加属性后,Patter.CASE_INSENSITIVE表示大小写不管
		Matcher m3 = p3.matcher("java_Java_jAva_jAVa_IloveJava");
		p(m3.replaceAll("JAVA"));//把所有的都替换为大写的
		
		p("------------------按照单双数替换");
		Pattern p4 = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//加属性后,Patter.CASE_INSENSITIVE表示大小写不管
		Matcher m4 = p4.matcher("java_Java_jAva_jAVa_IloveJava fdasfas");
		
		StringBuffer sb = new StringBuffer();
		int i = 0;
		while(m4.find()){
			i ++;
			if(i%2 == 0){
				m4.appendReplacement(sb, "java");
			}else{
				m4.appendReplacement(sb, "JAVA");
			}
		}
		m4.appendTail(sb);//把尾巴在再添加到buf上既是sb
		p(sb);
		
		p("------------------分组加括号只取数字一组");
		Pattern p5 = Pattern.compile("(\\d{3,5})([a-z]{2})");
		Matcher m5 = p5.matcher("123bb_78987dd_090po");
		
		while(m5.find()){
			p(m5.group(1));//grop括号里面第0组是整体,第一组是左起第一个括号,第二组是左起第二个括号
		}
		
		p("------------------贪婪的匹配与不贪婪匹配");
		Pattern p6 = Pattern.compile("(.{3,10}?)[0-9]");//.{3,10}后面没问号就是贪婪匹配会陪到最长,如果{3,10}?加?号就是懒蛋匹配之匹配最少的,从3个开始找
		Matcher m6 = p6.matcher("aaaa5dddd8");
		while(m6.find()){//如果这里用if(m6.find)(){p(m6.start()+"-"+m6.end());}  那么之匹配第一个
			p(m6.start()+"-"+m6.end());
		}
		
		p("------------------普通捕获");
		Pattern p7 = Pattern.compile(".{3}");
		Matcher m7 = p7.matcher("ab4dd5");
		while(m7.find()){
			p(m7.group());
		}
		
		p("------------------非捕获组");
		Pattern p8 = Pattern.compile(".{3}(?=a)");//(?=a)这个是非捕获组的意思,最后一个是a而且还不把这个a取出来!!(?=a)这个要是写在前面 就不一样了
		Matcher m8 = p8.matcher("ab4add5");
		while(m8.find()){
			p("后面不能是a的"+m8.group());
		}
		
		p8 = Pattern.compile("(?!a).{3}");//(?!a)前面不能是a的
		m8 = p8.matcher("abbsab89");
		while(m8.find()){
			p("前面不能是a的"+m8.group());
		}
		
		//(?<!a)从后往前数 不是a的
		//(?<=a)从后往前数 是a的
		p("------------------去除><号匹配");
		Pattern p9 = Pattern.compile("(?!>).+(?=<)");
		Matcher m9 = p9.matcher(">编程中国<");
		while(m9.find()){
			p(m9.group());
		}
		
		p("------------------向前引用");
		Pattern p10 = Pattern.compile("(\\d\\d)\\1");//这里面的1是向前引用,12是第一匹配到的,下一次在匹配出来12和前面相同 所以是true
		Matcher m10 = p10.matcher("1212");
		p(m10.matches());
		
		p("------------------忽略大小写,正则内嵌");//(?i)非捕获组里面这个表示忽略大小写
		p("java".matches("(?i)JAVA"));
	}
	
	public static void p(Object o){
		System.out.println(o);
	}
}

语法

字符 
x 字符 x 
\\ 反斜线字符 
\0n 带有八进制值 0 的字符 n (0 <= n <= 7) 
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) 
\0mnn 带有八进制值 0 的字符 mnn0 <= m <= 30 <= n <= 7) 
\xhh 带有十六进制值 0x 的字符 hh 
\uhhhh 带有十六进制值 0x 的字符 hhhh 
\t 制表符 ('\u0009') 
\n 新行换行 ('\u000A') 
\r 回车符 ('\u000D') 
\f 换页符 ('\u000C') 
\a 报警 (bell)  ('\u0007') 
\e 转义符 ('\u001B') 
\cx 对应于 x 的控制符 
  
字符类 
[abc] ab  c简单类) 
[^abc] 任何字符除了 ab  c否定) 
[a-zA-Z] a  z  A  Z两头的字母包括在内范围) 
[a-d[m-p]] a  d  m  p:[a-dm-p](并集) 
[a-z&&[def]] de  f交集) 
[a-z&&[^bc]] a  z除了 b  c:[ad-z](减去) 
[a-z&&[^m-p]] a  z而非 m  p:[a-lq-z](减去预定义字符类 
. 任何字符与行结束符可能匹配也可能不匹配) 
\d 数字:[0-9] 
\D 非数字: [^0-9] 
\s 空白字符:[ \t\n\x0B\f\r] 
\S 非空白字符:[^\s] 
\w 单词字符:[a-zA-Z_0-9] 
\W 非单词字符:[^\w] 
  
POSIX 字符类 US-ASCII) 
\p{Lower} 小写字母字符:[a-z] 
\p{Upper} 大写字母字符:[A-Z] 
\p{ASCII} 所有 ASCII:[\x00-\x7F] 
\p{Alpha} 字母字符:[\p{Lower}\p{Upper}] 
\p{Digit} 十进制数字:[0-9] 
\p{Alnum} 字母数字字符:[\p{Alpha}\p{Digit}] 
\p{Punct} 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 
\p{Graph} 可见字符:[\p{Alnum}\p{Punct}] 
\p{Print} 可打印字符:[\p{Graph}\x20] 
\p{Blank} 空格或制表符:[ \t] 
\p{Cntrl} 控制字符:[\x00-\x1F\x7F] 
\p{XDigit} 十六进制数字:[0-9a-fA-F] 
\p{Space} 空白字符:[ \t\n\x0B\f\r] 
  
java.lang.Character 类(简单的 java 字符类型) 
\p{javaLowerCase} 等效于 java.lang.Character.isLowerCase() 
\p{javaUpperCase} 等效于 java.lang.Character.isUpperCase() 
\p{javaWhitespace} 等效于 java.lang.Character.isWhitespace() 
\p{javaMirrored} 等效于 java.lang.Character.isMirrored() 
  
Unicode 块和类别的类 
\p{InGreek} Greek 块(简单块)中的字符 
\p{Lu} 大写字母(简单类别) 
\p{Sc} 货币符号 
\P{InGreek} 所有字符,Greek 块中的除外(否定) 
[\p{L}&&[^\p{Lu}]]  所有字母,大写字母除外(减去) 
  
边界匹配器 
^ 行的开头 
$ 行的结尾 
\b 单词边界 
\B 非单词边界 
\A 输入的开头 
\G 上一个匹配的结尾 
\Z 输入的结尾,仅用于最后的结束符(如果有的话) 
\z 输入的结尾 
  
Greedy 数量词 
X? X,一次或一次也没有 
X* X,零次或多次 
X+ X,一次或多次 
X{n} X,恰好 n 次 
X{n,} X,至少 n 次 
X{n,m} X,至少 n 次,但是不超过 m 次 
  
Reluctant 数量词 
X?? X,一次或一次也没有 
X*? X,零次或多次 
X+? X,一次或多次 
X{n}? X,恰好 n 次 
X{n,}? X,至少 n 次 
X{n,m}? X,至少 n 次,但是不超过 m 次 
  
Possessive 数量词 
X?+ X,一次或一次也没有 
X*+ X,零次或多次 
X++ X,一次或多次 
X{n}+ X,恰好 n 次 
X{n,}+ X,至少 n 次 
X{n,m}+ X,至少 n 次,但是不超过 m 次 
  
Logical 运算符 
XY X 后跟 Y 
X|Y X 或 Y 
(X) X,作为捕获组 
  
Back 引用 
\n 任何匹配的 nth 捕获组 
  
引用 
\ Nothing,但是引用以下字符 
\Q Nothing,但是引用所有字符,直到 \E 
\E Nothing,但是结束从 \Q 开始的引用 
  
特殊构造(非捕获) 
(?:X) X,作为非捕获组 
(?idmsux-idmsux)  Nothing,但是将匹配标志i d m s u x on - off 
(?idmsux-idmsux:X)   X,作为带有给定标志 i d m s u x on - off 
的非捕获组  (?=X) X,通过零宽度的正 lookahead 
(?!X) X,通过零宽度的负 lookahead 
(?<=X) X,通过零宽度的正 lookbehind 
(?<!X) X,通过零宽度的负 lookbehind 
(?>X) X,作为独立的非捕获组 

📝 首页

🌏 知识星球码农会锁

实战项目:「DDD+RPC分布式抽奖系统」、专属小册、问题解答、简历指导、架构图稿、视频课程

🐲 头条

⛳ 目录

  1. 源码 - :octocat: 公众号:bugstack虫洞栈 文章所涉及到的全部开源代码
  2. Java
  3. Spring
  4. 面向对象
  5. 中间件
  6. Netty 4.x
  7. 字节码编程
  8. 💯实战项目
  9. 部署 Dev-Ops
  10. 📚PDF 下载
  11. 关于

💋 精选

🐾 友链

建立本开源项目的初衷是基于个人学习与工作中对 Java 相关技术栈的总结记录,在这里也希望能帮助一些在学习 Java 过程中遇到问题的小伙伴,如果您需要转载本仓库的一些文章到自己的博客,请按照以下格式注明出处,谢谢合作。

作者小傅哥
链接https://bugstack.cn
来源bugstack虫洞栈

2021年10月24日,小傅哥 的文章全部开源到代码库 CodeGuide 中,与同好同行,一起进步,共同维护。

这里我提供 3 种方式:

  1. 提出 Issue :在 Issue 中指出你觉得需要改进/完善的地方(能够独立解决的话,可以在提出 Issue 后再提交 PR )。
  2. 处理 Issue : 帮忙处理一些待处理的 Issue
  3. 提交 PR: 对于错别字/笔误这类问题可以直接提交PR,无需提交Issue 确认。

详细参考:CodeGuide 贡献指南 - 非常感谢你的支持,这里会留下你的足迹

  • 加群交流 本群的宗旨是给大家提供一个良好的技术学习交流平台,所以杜绝一切广告!由于微信群人满 100 之后无法加入,请扫描下方二维码先添加作者 “小傅哥” 微信(fustack),备注:加群。
微信:fustack

  • 公众号(bugstack虫洞栈) - 沉淀、分享、成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获。
公众号:bugstack虫洞栈

感谢以下人员对本仓库做出的贡献或者对小傅哥的赞赏,当然不仅仅只有这些贡献者,这里就不一一列举了。如果你希望被添加到这个名单中,并且提交过 Issue 或者 PR,请与我联系。

Clone this wiki locally