Java正则表达式-详解(附相关真题)

Wendy ·
更新时间:2024-11-14
· 910 次阅读

目录正则表达式1. 正则标记1.1 字符1.2 字符类1.3 预定义字符类1.4 边界匹配器(java一般不用到)1.5 Greedy 数量词1.6 Logical 运算符2. String类支持3. Java.util.regex包支持3.1 Pattern类(常用方法)3.2 Matcher类(常用方法)4. 简单运用4.1 邮箱格式验证4.2 SQL语句内容抽取4.3 数字验证4.4 匹配分组加多次匹配5. 真题5.1 压缩算法5.2 音节判断5.3 正则表达式匹配(剑指Offer 面试题19) 正则表达式

概述:描述了一种字符串匹配的模式,用来检查一个串是否含有某个子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
应用场景:邮箱、IP格式等的验证处理,复杂字符串的内容替换或修改处理等。

1. 正则标记

由Java.util.regex开发包中Pattern程序类定义,这里参考JDK6.0的API文档,列举出了常用的基本符号。

1.1 字符
元字符 描述
x 字符x
\\ 反斜线字符
\t 制表符
\n 换行符
\r 回车符
\f 换页符
1.2 字符类
元字符 描述
[abc] a、b或c中任意一个字符(简单类)
[^abc] 除了 a、b、c的任意一个字符(否定)
[a-zA-Z] 大小写字母中的任意一个字符,两头的字母包括在内(范围)
[a-d[m-p]] a到d加上m到p的任意一个字符:[a-dm-p](并集)
[a-z&&[def]] d、e、f中的一个字符(交集)
[a-z&&[^bc]] a到z,但是除去b、c的任意一个字符:[ad-z](减去)
[a-z&&[^m-p]] = [a-z && [a-lq-z] ] = [a-lq-z](减去)
1.3 预定义字符类
元字符 描述
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符(空格,换行,制表符等):[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
1.4 边界匹配器(java一般不用到)
元字符 描述
^ 行的开头
$ 行的结尾
1.5 Greedy 数量词
元字符 描述
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
1.6 Logical 运算符
元字符 描述
XY X 后跟 Y
X|Y X 或 Y
(X) X,作为捕获组(分组匹配可用到)
2. String类支持

1)在JDK1.4之后,正则已经默认被JDK支持,不用导入其他的*.jar 包;
2)正则表达式大部分处理情况都会基于String类来完成;
3)String类对正则的支持满足拆分、替换、匹配三种操作。

描述 方法
将指定字符串进行正则判断 public Boolean matches(String regex)
替换全部 public String replaceAll(String regex , String replacement)
替换首个 public String replaceFirst(String regex , String replacement)
正则拆分 public String[] split(String regex)
正则拆分(添加应用次数) public String[] split(String regex , int limit)
3. Java.util.regex包支持

如果纯粹的是以拆分、替换、匹配三种操作为例根本用不到 java.util.regex开发包,只依靠 String类就都可以实现了。但是Java.util.regex包可以进行一些更为复杂的正则处理,如:匹配分组,多次匹配等操作。
Java.util.regex包提供有Pattern、Mather两个类。Pattern类进行正则表达式的编译,而Matcher类进行正则匹配,可将两者搭配起来进行复杂的正则处理。

3.1 Pattern类(常用方法)
描述 方法
正则表达式的编译处理 public static Pattern compile(String regex)(静态方法,可预编译提高效率)
拆分 public String[] split(CharSequence input)
匹配 public Matcher matcher(CharSequence input)
编译加匹配 public static boolean matches(String regex,CharSequence input)
3.2 Matcher类(常用方法)
描述 方法
对整个字符串进行匹配 public boolean matches()
对字符串开头进行匹配 public boolean lookingAt()
对字符串任意位置进行匹配 public boolean find()
匹配字符串在母串中的index public int start()
匹配字符串的最后一个字符在母串中的index+1 public int end()
匹配到的字符串 public String group()

1)在执行过上述返回boolean值的方法之后,可以执行m.start()、m.end()、m.group()返回匹配细节。
2)start、end和group方法也可以用参数指定获取哪个分组的细节,整个模式自身算是第0个分组。

4. 简单运用 4.1 邮箱格式验证 String str1 = "abc123456_7@qq.com"; String str2 = "_Abc1234567@qq.com"; String regex = "[a-zA-Z0-9]\\w+@\\w+\\.(cn|com|com.cn|net|gov)"; System.out.println(str1.matches(regex)+" "+str2.matches(regex)); //str1返回true,str2返回false。 //[a-zA-Z0-9]表示大小写字母和数字中任意一个字符,\w表示字母数字下划线的任意一个,表达式后面有个加号表示多个,(cn|com|com.cn|net|gov)表示满足一个即可。 4.2 SQL语句内容抽取 String str = "INSERT INTO dept(deptno,dname,loc) VALUES (#{deptno},#{dname},#{loc})"; String regex = "#\\{\\w+\\}"; Pattern pat = Pattern.compile(regex);//编译 Matcher mat = pat.matcher(str); while(mat.find()){//是否有匹配成功的内容 System.out.println(mat.group(0).replaceAll("#|\\{|\\}", "")+" ");//替换,去掉#{}并输出 } //内容输出为deptno dname loc 4.3 数字验证 String regex6="[+|-]?\\d+(\\.\\d+)?([e|E][+|-]?\\d+)?"; System.out.println(isNumber("+-123",regex6));//false System.out.println(isNumber("-123",regex6));//true System.out.println(isNumber("+123",regex6));//true System.out.println(isNumber("123",regex6));//true System.out.println(isNumber("5.6e2",regex6));//true System.out.println(isNumber("-1E-23",regex6));//true System.out.println(isNumber("3.1415",regex6));//true System.out.println(isNumber("3.1415e8990",regex6));//true System.out.println(isNumber("3.1415e89.90",regex6));//false public static boolean isNumber(String str,String regex){ return str.matches(regex); } 4.4 匹配分组加多次匹配 String str="AA[BB[CCDD[EEFFGG[HH]]]]"; String regex="([A-Z]+)\\[([A-Z]+)\\]"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); while(matcher.find()){ String temp = ""; for (int i = 1; i <= matcher.groupCount(); i++) { System.out.print(matcher.group(i)+" "); temp = temp + matcher.group(i); }System.out.println(); str = matcher.replaceAll(temp); matcher = pattern.matcher(str); } /* * 运行结果: * EEFFGG HH CCDD EEFFGGHH BB CCDDEEFFGGHH AA BBCCDDEEFFGGHH */ 5. 真题 5.1 压缩算法

腾讯2020校园招聘-后台

小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?

输入描述:
输入第一行包含一个字符串s,代表压缩后的字符串。
S的长度<=1000;
S仅包含大写字母、[、]、|;
解压后的字符串长度不超过100000;
压缩递归层数不超过10层;

输出描述:
输出一个字符串,代表解压后的字符串。

输入例子1:
HG[3|B[2|CA]]F

输出例子1:
HGBCACABCACABCACAF

import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { static String regex = "\\[(\\d+)\\|(\\w+)\\]"; static Pattern pattern = Pattern.compile(regex); public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = scanner.next(); Matcher matcher = pattern.matcher(s); while (matcher.find()) { // System.out.print(matcher.group(1) + " " + matcher.group(2) + // " ");//分组、括号()是关键 int num = Integer.parseInt(matcher.group(1)); String temp = ""; for (int i = 0; i < num; i++) { temp += matcher.group(2); } s = matcher.replaceAll(temp); // System.out.println(s); matcher = pattern.matcher(s); } System.out.println(s); } } 5.2 音节判断

2020年蓝桥杯模拟赛解题报告

【问题描述】小明对类似于 hello 这种单词非常感兴趣,这种单词可以正好分为四段,第一段由一个或多个辅音字母组成,第二段由一个或多个元音字母组成,第三段由一个或多个辅音字母组成,第四段由一个或多个元音字母组成。给定一个单词,请判断这个单词是否也是这种单词,如果是请输出yes,否则请输出no。元音字母包括 a, e, i, o, u,共五个,其他均为辅音字母。
【输入格式】输入一行,包含一个单词,单词中只包含小写英文字母。
【输出格式】输出答案,或者为yes,或者为no。
【样例输入】lanqiao
【样例输出】yes
【样例输入】world
【样例输出】no
【评测用例规模与约定】对于所有评测用例,单词中的字母个数不超过100。

import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public Main { static Pattern p = Pattern.compile("[^aeiou]+[aeiou]+[^aeiou]+[aeiou]+"); static Scanner sc = new Scanner(System.in); public static void main(String[] args) { while (true) { //死循环是为了测试 if (work()) System.out.println("yes"); else System.out.println("no"); } } static boolean work() { String word = sc.nextLine(); Matcher m = p.matcher(word); return m.matches(); } } 5.3 正则表达式匹配(剑指Offer 面试题19)

请实现一个函数用来匹配包括 ‘.’ 和 ‘*’ 的正则表达式。模式中的字符 ‘.’ 表示任意一个字符,而 ‘*’ 表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。

public class Main { public static void main(String[] args) { System.out.println(matchCore("aaa", "a.a", 0, 0)); // true System.out.println(matchCore("aaa", "ab*ac*a", 0, 0)); // true System.out.println(matchCore("aaa", "aa.a", 0, 0)); // false System.out.println(matchCore("aaa", "ab*a", 0, 0)); // false System.out.println(matchCore("aaa", "*a.a", 0, 0)); // false } public static boolean matchCore(String str, String regex, int sIndex, int rIndex) { int slen = str.length(); int rlen = regex.length(); // 同时遍历完才算成功 if (sIndex == slen && rIndex == rlen) { return true; } if (sIndex == slen && rIndex != rlen) { return false; } if (sIndex != slen && rIndex == rlen) { return false; } // 第二个字符为‘*’的情况 if (rIndex + 1 < rlen && regex.charAt(rIndex + 1) == '*') { if (regex.charAt(rIndex) == str.charAt(sIndex) || (regex.charAt(rIndex) == '.' && sIndex < slen)) { return matchCore(str, regex, sIndex + 1, rIndex + 2) // ‘*’为1 || matchCore(str, regex, sIndex + 1, rIndex) // ‘*’为n || matchCore(str, regex, sIndex, rIndex + 2); // ‘*’为0 } else { return matchCore(str, regex, sIndex, rIndex + 2); } } if (regex.charAt(rIndex) == str.charAt(sIndex) || (regex.charAt(rIndex) == '.' && sIndex < slen)) { return matchCore(str, regex, sIndex + 1, rIndex + 1); } return false; } }
作者:_青红_



java正则 java正则表达式 真题 JAVA

需要 登录 后方可回复, 如果你还没有账号请 注册新账号