灵活地运用正则表达式,必须了解各种元字符的功能,以下分成:
public static void main(String[] args) {
String content = "在1998年12月11日到2004年2月12日";
System.out.println("-------一、捕获分组---------");
System.out.println("------------1.非命名分组()--------");
String regStr = "(\\d\\d)(\\d)(\\d)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("第一个字符串"+matcher.group(0));
System.out.println("第一组()"+matcher.group(1));
System.out.println("第二组()"+matcher.group(2));
System.out.println("第三组()"+matcher.group(3));
}
System.out.println("--------2.命名分组(?)----------" );
String regStr1 = "(?\\d\\d)(?\\d\\d)" ;
Pattern pattern1 = Pattern.compile(regStr1);
Matcher matcher1 = pattern1.matcher(content);
while(matcher1.find()){
System.out.println("第一个字符串"+matcher1.group(0));
System.out.println("第一组"+matcher1.group("g1"));
System.out.println("第二组"+matcher1.group("g2"));
}
}
输出:
-------一、捕获分组---------
------------1.非命名分组()--------
第一个字符串1998
第一组()19
第二组()9
第三组()8
第一个字符串2004
第一组()20
第二组()0
第三组()4
--------2.命名分组(?<name>)----------
第一个字符串1998
第一组19
第二组98
第一个字符串2004
第一组20
第二组04
2. 非捕获分组:不能使用matcher.group(i) 当i>=1
System.out.println("-------二、非捕获分组---------");
String content01 = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello";
// 目标:找到 韩顺平教育 韩顺平老师 韩顺平同学
System.out.println("-----(?:)------");
String regstr01 = "韩顺平(?:教育|老师|同学)";
Pattern pattern01 = Pattern.compile(regstr01);
Matcher matcher01 = pattern01.matcher(content01);
while(matcher01.find()){
System.out.println(matcher01.group(0));
}
// 目标:找到 韩顺平教育 韩顺平老师 中的韩顺平
System.out.println("-----(?=)------");
String regstr02 = "韩顺平(?=教育|老师)";
Pattern pattern02 = Pattern.compile(regstr02);
Matcher matcher02 = pattern02.matcher(content01);
while(matcher02.find()){
System.out.println(matcher02.group(0));
}
// 目标:找到除了 韩顺平教育 韩顺平老师 中的韩顺平
System.out.println("-----(?!)------");
String regstr03 = "韩顺平(?!教育|老师)";
Pattern pattern03 = Pattern.compile(regstr03);
Matcher matcher03 = pattern03.matcher(content01);
while(matcher03.find()){
System.out.println(matcher03.group(0));
}
输出:
-------二、非捕获分组---------
-----(?:)------
韩顺平教育
韩顺平老师
韩顺平同学
-----(?=)------
韩顺平
韩顺平
-----(?!)------
韩顺平
在Java中用" \ \ “表示其他语言的 ’ \ ',比如要找“abc$(abc(123(”里面的‘(’,表达式为” \ \ ( "
注意:如果你想要的符号写在[]里面,就不用加\\,例如:上面表达式也可以写成 " [(] "
这里修正和补充一下:
\ \ w表示匹配单个 数字、大小写字母、下划线;
\ \ s匹配任意空白字符(空格,制表符等);
\ \ S匹配任意非空白字符;
. 表示匹配除\n的所有字符。
@Test
public void method03(){
String content = "abca 11c8Abc 李";
// 使用 | 选择匹配符找到abc A 李 任意一个
String regStr = "abc|A|李";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println(matcher.group(0));
}
}
输出:
abc
A
李
限定符就是要限定匹配字符的个数
补充一下:abc{3}表示匹配adccc。 a{3,4}表示匹配aaa或者aaaa,但是优先匹配4个a【贪婪匹配】
综合一下:以上所有限定符都会满足贪婪匹配,优先匹配最大范围的结果
定位符就是规定匹配字符串出现的位置,比如指定在字符串开始还是结束的位置
贪婪匹配,优先匹配最大范围的结果;非贪婪匹配则与之相反,下面演示一下:
所有正则式默认都是贪婪匹配,非贪婪匹配只需在语句后面加上?
public void method04(){
String content = "abccca 11c8Abc 李";
String regStr1 = "\\d+"; // 贪婪匹配
Pattern pattern = Pattern.compile(regStr1);
Matcher matcher = pattern.matcher(content);
System.out.println("贪婪匹配:");
while(matcher.find()){
System.out.println(matcher.group(0));
}
String regStr2 = "\\d+?"; // 非贪婪匹配
Pattern pattern2 = Pattern.compile(regStr2);
Matcher matcher2 = pattern2.matcher(content);
System.out.println("非贪婪匹配:");
while(matcher2.find()){
System.out.println(matcher2.group(0));
}
}
结果:
贪婪匹配:
11
8
非贪婪匹配:
1
1
8
package RegularExpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author 神代言
* @version 1.0
*/
public class RegExpExercise {
public static void main(String[] args) {
// 1.汉字:
// 解释:^起始位置,$结束为止,
// String content = "一万年可长否";
// String regStr = "^[\u0391-\uffe5]+$";
// 2.邮政编码要求:1-9开头的一个六位数
// String regStr = "^[1-9]\\d{5}$";
// 3.QQ号码要求:1-9开头的一个5-10位数
// String regStr = "^[1-9]\\d{4,9}$";
// 4.手机号码:要求13、14、15、18开头的11位数
// String regStr = "^1[3|4|5|8]\\d{9}$";
// 5.验证URL:
String content = "https://www.bilibili.com/video/BV1fh411y7R8/?p=894" +
"&spm_id_from=pageDriver&vd_source=b6cd1b2cafcf0b55448eb890ac82becf";
// 第一部分验证:https://
// 第二部分验证:www.bilibili.com
// 第三部分验证:/video/BV1fh411y7R8/?p=894&spm_id_from=pageDriver&vd_source=b6cd1b2cafcf0b55448eb890ac82becf
String regStr = "^((http|https)://)" + "([\\w-]+\\.)+[\\w-]+"
+ "(/[\\w-?=&/%.]*)?$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
System.out.println("验证成功");
}
}
}
这里演示在指定字符串中找到不区分大小的“abc”
public void method02(){
String content = "abca11c8Abc";
String regStr = "abc";
// Java默认区分大小写,这里演示如何不区分大小写
// 方式一:regStr =
// (?i)abc 表示abc不区分大小写
// a(?i)bc 表示bc不区分大小写
// a((?i)b)c 表示b不区分大小写
// 方式二:Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println(matcher.group(0));
}
}
输出:
abc
Abc
public class PatternMethod {
public static void main(String[] args) {
String content = "hello abc hello, 韩顺平教育";
//String regStr = "hello abc hello, 韩顺平教育"; // -> true
String regStr = "hello.*"; // -> true
boolean matches = Pattern.matches(regStr, content);
System.out.println("整体匹配= " + matches);
// 一般使用使用整体匹配验证字符串是否满足规则
// Pattern.matches(regStr, content)
// 成功返回true
}
}
package RegularExpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author 神代言
* @version 1.0
*/
public class MatcherMethod {
public static void main(String[] args) {
String content = "hello edu jack hspedutom hello smith hello hspedu hspedu";
String regStr = "hello";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("=================");
System.out.println(matcher.start());
System.out.println(matcher.end());
System.out.println("找到: " + content.substring(matcher.start(), matcher.end()));
}
//整体匹配方法,常用于,去校验某个字符串是否满足某个规则
System.out.println("整体匹配=" + matcher.matches());
//完成如果content 有 hspedu 替换成 韩顺平教育
regStr = "hspedu";
pattern = Pattern.compile(regStr);
matcher = pattern.matcher(content);
//注意:返回的字符串才是替换后的字符串 原来的 content 不变化
String newContent = matcher.replaceAll("韩顺平教育");
System.out.println("newContent=" + newContent);
System.out.println("content=" + content);
}
}
public class RegExp01 {
public static void main(String[] args) {
String content = "h1234el9876lo33333 j12324-333999111a1551ck14 tom11 jack22 yyy12345 xxx";
//要匹配两个连续的相同数字 : (\\d)\\1
//String regStr = "(\\d)\\1";
//要匹配五个连续的相同数字: (\\d)\\1{4}
//String regStr = "(\\d)\\1{4}";
//要匹配个位与千位相同,十位与百位相同的数 5225 , 1551 (\\d)(\\d)\\2\\1
//String regStr = "(\\d)(\\d)\\2\\1";
/**
* 请在字符串中检索商品编号,形式如:12321-333999111 这样的号码,
* 要求满足前面是一个五位数,然后一个-号,然后是一个九位数,连续的每三位要相同
*/
String regStr = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到 " + matcher.group(0));
}
}
}
实例:经典的结巴程序
public class RegExp02 {
public static void main(String[] args) {
String content = "我....我要....学学学学....编程java!";
// 去掉重复的句子,将上面编程:我要学编程Java!
//1. 去掉所有的.
Pattern pattern = Pattern.compile("\\.");
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
// System.out.println("content=" + content);
//2. 去掉重复的字 我我要学学学学编程java!
// 思路
//(1) 使用 (.)\\1+
//(2) 使用 反向引用$1 来替换匹配到的内容
// 注意:因为正则表达式变化,所以需要重置 matcher
pattern = Pattern.compile("(.)\\1+");//分组的捕获内容记录到$1
matcher = pattern.matcher(content);
while (matcher.find()) {
System.out.println("找到=" + matcher.group(0));
}
//使用 反向引用$1 来替换匹配到的内容
content = matcher.replaceAll("$1");
System.out.println("content=" + content);
//3. 使用一条语句 去掉重复的字 我我要学学学学编程java!
// content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
// System.out.println("content=" + content);
}
}
public class RegExp03 {
public static void main(String[] args) {
String content = "2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其" +
"获得了Apple公司Mac OS X的工业标准的支持。2001年9月24日,J2EE1.3发" +
"布。" +
"2002年2月26日,J2SE1.4发布。自此Java的计算能力有了大幅提升";
//使用正则表达式方式,将 JDK1.3 和 JDK1.4 替换成JDK
content = content.replaceAll("JDK1\\.3|JDK1\\.4", "JDK");
System.out.println(content);
}
}
public static void main(String[] args) {
// 验证功能:要求手机号必须138 139开头
String content = "13888889999";
if (content.matches("1(38|39)\\d{8}")) {
System.out.println("验证成功");
} else {
System.out.println("验证失败");
}
}
public static void main(String[] args) {
// 分割功能:
// 要求按照 # 或者 - 或者 ~ 或者 数字 来分割
System.out.println("===================");
content = "hello#abc-jack12smith~北京";
String[] split = content.split("#|-|~|\\d+");
for (String s : split) {
System.out.println(s);
}
}
特别说明
本文章是个人整理的学习笔记,参考b站韩顺平老师的课程(【零基础 快速学Java】韩顺平 零基础30天学会Java)。老师讲的非常好,有兴趣的可以去看一下。