正则表达式
正则表达式三个常用类
java.util.regex包括以下三个类Pattern类,Matcher类和PatternSyntaxException
Pattern类
pattern对象时一个正则表达式对象,Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,返回一个Pattern对象。该方法接收一个正则表达式作为它的一个参数,比如: Pattern r = Pattern.compile(pattern);
Matcher类
Matcher 对象时对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象
PatternSyntaxException
PatternSyntaxException 是一个非常强制异常类,它表示一个正则表达式模式中的语法错误。
正则表达式API
package cn.itcast.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 体验正则表达式的为例,给我们文本 处理带来哪写便利
* */
public class RegexpDemo01 {
public static void main(String[] args) {
// 假设我们使用
String content = "Apache Hive是一款建立在Hadoop之上的开源数据仓库系统," +
"可以将存储在Hadoop文件中的结构化,半结构化数据文件映射为一张数据库表," +
"基于表提供了一种类似SQL的查询模块,称为Hive查询语言(HQL),用于访问和" +
"分析存储在Hadoop文件中的大型数据集。";
// 需求提取字符串中所有的英文单词
// 1,传统方法,说你遍历方式,代码量大,效率不高
// 2 .正则表达式技术
// 1.想创建一个Pattern对象,模式对象,可以理解成就是一个正则表达式对象
Pattern pattern = Pattern.compile("[a-zA-Z]+");
//2.创建一个匹配器对象
// 理解:就是matcher匹配器按照 pattern(模式/样式),到content 文本中取匹配
Matcher matcher = pattern.matcher(content);
// 3.可以开始循环匹配
while(matcher.find()){
// 匹配内容,文本,放到 matcher.group(0)
System.out.println("找到:"+matcher.group(0));
}
}
}
正则表达式底层实现(重要)
package cn.itcast.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 分析java的底层实现(重要)
* */
public class RegTheory {
public static void main(String[] args) {
String content = " 1998年12月8日,第二代Java平台企业版J2EE发布。1999年6月," +
"Sun发布了“+”第二代Java平台(以下简称Java2)三个版本:J2ME (Java2 Micro版,Java2平台" +
"的微型版“+”),用于移动、无线和资源有限的环境;J2SE (Java 2 Standard Edition, Java " +
"2平台的“+”标准版本,应用于桌面环境;在基于Java的应用服务器上,J2EE (Java 2 enterprise" +
" Edition, Java 2 platform, enterprise Edition)应该是3443中的“+”。Java 2平台的发布" +
",是Java开发过程中最重要的里程碑之一, 9889标志着Java应用的开始普及。";
// 目标:匹配所有四个数字
// 说明
// 1、\\d表示一个任意的数字
String regStr = "(\\d\\d)(\\d\\d)";
// 2、创建一个模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
// 3、创建匹配器
// 说明:创建匹配器matcher,按照正则表达式的规则去匹配content字符串
Matcher matcher = pattern.matcher(content);
// 4.开始匹配
/*
* match.find()完成任务(考虑分组)
* 什么事分组,比如(\\d)(\\d),正则表达式中有() 表示分组 ,第一个()表示第一组,第二个小括号表示第二组....
* 1.更苦指定的规则,定位满足规则的子字符串(比如1998)
* 2.找到后,将子字符串的开始索引记录到matcher对象的属性 int[] groups;
* groups[0] = 0, 把该子字符串的结束的索引记录到groups[1] =4
* 3.同时记录oldLast的值为子字符串的结束的索引+1的值即4,即下次执行find时,就从4开始匹配
*
* matcher.group(0)分析
* 源码:
* public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
* 1、根据 groups[0]=0 和groups[1]=4 的记录的位置,从content开始截取子字符串返回
* 就是[0,4) 包含 0 但是不包含索引为4的位置
*
* 如果再次执行find方法,仍然按照上面的执行
*
*
* */
while (matcher.find()) {
System.out.println("找到:" + matcher.group(0));
System.out.println("第1组()匹配到的值=" +matcher.group(1));
System.out.println("第2组()匹配到的值="+matcher.group(2));
// System.out.prinltn(matcher.group(3));这里是会报错的,因为没有第三组,所以在取第三组的时候会报错
/*
这里group(1)表示返回的是第一组,第一组是指,在正则表达式第一个括号匹配的的值的
索引,group(2)表示第二组,group(0)表示没有分组,也就是在没有括号的情况下取的正
则表达式匹配到的一个整体
*/
}
}
}
/*
总结 :如果正则表达式有() 即分组,取出匹配的字符串规则如下
group(0) 表示匹配到的子字符串
group(1) 表示匹配到的整体的子字符串的第一组字串
group(2) 表示匹配到的子字符串的第2组字符串
.....但是分组的数不能越界.
*/
正则表达式语法
基本介绍
如果想灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合和方向引用符
- 特殊字符
- 定位符
元字符-转义号\
- \\符号-说明:在我们使用正则表达式取检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错的。案例:用 取匹配“ a b c 取匹配“abc 取匹配“abc(” 会怎样,用(取匹配“abc$"会怎样?
- 再次提示:在java的正则表达式中,两个\代表其他语言中的一个\
- 需要用到转义符号的字符有以下:. * + ( ) $ / \ ? [ ] ^ { }
案例
public class Regexp02{ public static void main(String[] args){ String content = "abc$(abc(123("; // 匹配( String regStr = "\\("; Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while(matcher.find()){ System.out.println("找到"+matcher.group(0)); } } }
元字符-字符匹配符
符号 含义 实例 解释 匹配输入 [ ] 可接收的字符列表 [efgh] e、f、g、h中的任意1个字符 [^] 不接收的字符列表 [^abc] 除a、b、c之外的任意1个字符,包括数字和特殊符号 - 连字符 A-Z 任意单个大写字母 . 匹配\n以外的任何字符 a…b 以a开头,b结尾,中间包括2个任意字符的长度为4的字符串 aaab,aefb \\d 匹配单个数字字符,相当于[0-9] \\d{3}(\\d)? 包含3个或4个数字的字符串,?表示有0个或1个数字 123,9876 \\D 匹配单个非字符字符,相当[^0-9] \\D(\\d)* 以单个非数字字符开头,后接任意个数字字符串 a、A342 \\w 匹配单个数字,大小写字母字符,相当于[^0- 9a
-zA-z]\\d{3}\\w{4} 以至少1个非数字字母开头的长度为7的数字字母字符串 234abcd、12345Pe \\W 匹配单个非数字,大小写字母字符,相当于[^0-9a-zA-Z] \\w+\\d{2} 以至少1个非数字字母字符开头,2个数字字符结尾的字符串 #29、#?@10 \\s 匹配任何空白字符(空格,制表符,等 ) \\S 匹配任何非空字符 案例:
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegExp03 { public static void main(String[] args) { String content = "allc8ab_cA\n BC@"; // String regStr = "[a-z]";//匹配 a-z 之间任意一个字符一个字符 // String regStr = "[A-Z]";//匹配 A-Z 之间任意一个字符一个字符 // String regStr = "abc";//匹配 abc 字符串[默认区分大小写] // String regStr = "(?i)abc"; //匹配 abc 字符串 // String regStr = "[abcd]"; //匹配abcd任意一个字符 // String regStr = "\\D"; //匹配 不在0-9的任意一个字符 // String regStr = "\\w"; //匹配 任意字母和数字,下划线 // String regStr = "\\W"; //匹配 处理字母和数字,下划线 // String regStr = "\\s"; //匹配 任何空白字符 // String regStr = "\\S"; //匹配 任何空白字符 String regStr = "."; //匹配 任何空白字符 // 说明 //1.当川建安Pattern对象时,指定 Pattern.CASE_INSENSITIVE,表示匹配是不区分字母大小写, Pattern pattern = Pattern.compile(regStr); Matcher matcher1 = pattern.matcher(content); while (matcher1.find()) { System.out.println("找到" + matcher1.group(0)); } } }
[^a-z] 说明:
[^a-z]表示可以匹配不是a-z中的任意一个字符
[^A-Z]表示可以匹配不是A-Z中的任意一个字符。
[^0-9]表示可以匹配不是0-9中的任意一个字符。
这个就不举例说明了。
元字符-选择匹配符
在匹配某个字符串的时候是选择性的,即:既可以匹配这个,又可以匹配那个,这时你需要用到选择匹配符 |
符号 符号 示例 解释 | 匹配 “|”之前或之后的表达式 ab|cd ab或者cd package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 选择匹配符 * */ public class Regexp04 { public static void main(String[] args){ String content = "hanshunping 就 寒冷"; String regStr = "han|就|寒"; Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while(matcher.find()){ System.out.println("找到"+matcher.group(0)); } } }
元字符-限定符
用于指定其前面的字符和组合项链连续出现多少次
符号 含义 实例 说明 匹配输入 * 指定字符重复0次或n次(无要求)零到多 (abc) 仅包含任意个abc的字符串,等效于\w* abc/abcabcabc + 指定字符重复1次或n次,1到多 m+(abc)* 以至少1个m开头,后接任意个abc的字符串 m,mabc,mabcabc ? 指定字符重复0次或1次(最多1次) m+abc? 以至少1个m开头,后接ab或abc的字符串 mab,mabc {n} 只能输入n个字符 [abcd]{3} 由abcd中字母组成的任意长度3的字符串 abc,dbc,adc {n,} 指定至少n个匹配 [abcd]{3,} 由abcd中字母组成的任意长度不小于3的字符串 aab、dbc、aaabdc {n, zm} 指定至少n个但不多于m个匹配 [abcd][3,5] 又abcd中字母组成的任意长度不小于3,不大于5的字符串 abc,abcd,aaaaa,bcdab 案例
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 演示限定符的使用 * */ public class Regexp05 { public static void main(String[] args) { String content = "a1111111aaaaaa1hello"; // a{3},1{4},(\\d){2} // String regStr = "a{3}"; // 表示匹配 aaa // String regStr = "1{3}"; // 表示匹配 1111 // String regStr = "\\d{2}"; // 表示匹配 两位的任意数字字符 // 细节:java匹配默认贪婪匹配,即尽可能匹配多的 // String regStr = "a{3,4}"; // 表示匹配 3个a最多4个a // String regStr = "\\d{3,4}"; // 表示匹配 4个任意数字或3个任意数字 // 1+ // String regStr = "1+"; // 匹配一个1或者多个1 // String regStr = "\\d+"; // 匹配一个数字或者多个数字 // 1* // String regStr = "1*"; //匹配0个或者多个1 // 样式?的使用,遵守贪婪匹配 // String regStr = "a1?"; //匹配0个或者多个1 String regStr = "a1?"; //匹配0个或者多个1 Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到" + matcher.group(0)); } } }
元字符-定位符
- 定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的,必须掌握
符号 含义 实例 说明 匹配输入 ^ 指定其实字符 1+[a-z] 已至少1个数字开头,后接任意个小写字母的字符串 123,6aa,555edf $ 指定结束字符 2\\-[a-z]+$ 以1个数字开头后接连字符“-”,并以至少1个小写字母结尾的字符串 1-a \\b 匹配目标字符串的边界 han\\b 这里说的字符串的边界指的是子串间有空格,或者目标字符串的结束位置 hanshunping sphan nnhan \B 匹配目标字符存的非边界 han\\b 和\b的含义刚刚相反 hanshunping sphan nnhan 案例
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 演示定位符的使用 * */ public class Regexp06 { public static void main(String[] args){ // String content = "123-abc"; String content = "hanshunping hansphan\n nnhan"; //以至少1个数字开头,后接任意个小写字母的字符串 // String regStr = "^[0-9]+[a-z]*"; // 表示匹配以数字开头1到多个,结尾字母0到多个 // String regStr = "^[0-9]+[a-z]+$"; // 表示以至少1个数字开头,必须以至少一个小写字母结束 // String regStr = "^[0-9]+\\-[a-z]+$"; // 表示以至少1个数字开头,必须以至少一个小写字母结尾,同时中间还要有一个- // String regStr = "han\\b"; // 表示要匹配边界的han,[这里的边界是指:被匹配的字符串的最后,也可以是空格的子字符串的后面] String regStr = "han\\B"; // 跟上面是完全相反的,匹配开头且后面没有空格或空格制表符的字符 Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while(matcher.find()){ System.out.println("找到="+matcher.group(0)); } } }
捕获分组
常用分组构造形式 说明 (pattern) 非命名捕获,捕获匹配的字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始指定编号 (?pattern) 命名捕获。将匹配的子字符串捕获到一个组名称或编号名称中。用于nam的字符串不能包含任何标点符号,并且不能以数字开头,可以使用单引号代替尖括号,例如(?‘name’ ) 案例:
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp07 { public static void main(String[] args) { String content = "hanshunping s4343 nn4648han"; // String regStr = "\\d{4}"; // 匹配4个整数 // 下面就是非命名分组 // 说明 // 1、matcher.group(0) 得到匹配到的字符串 // 2、matcher.group(1) 得到匹配到的字符串的第1个分组内容 // 3、matcher.group(2) 得到匹配到的字符串的第2个分组内容 // String regStr = "(\\d\\d)(\\d\\d)"; // 匹配2个组的数字,两个组分别是2个数字 // String regStr = "(\\d\\d)(\\d)(\\d)"; // 匹配4个数字,分为3个组,第一个数2个数字,第2,3个组1个数字 //命名分组:即可以给分组取名 String regStr = "(?<g1>\\d\\d)(?<g2>\\d)(\\d)"; // 匹配4个字符串,并给分组起名字,可以通过分组名来进行获取 Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { // 使用分组序号来获取字符 System.out.println("找到:" + matcher.group(0)); System.out.println("第1个分组的内容:" + matcher.group(1)); System.out.println("第2个分组的内容:" + matcher.group(2)); System.out.println("第3个分组的内容:" + matcher.group(3)); // 使用分组名称来获取字符 System.out.println("第1个分组的内容[通过名称获取]:" + matcher.group("g1")); System.out.println("第2个分组的内容[通过名称获取]:" + matcher.group("g2")); } } }
特别分组
常用分组构造形式 说明 (?:pattern) 匹配pattern但是不捕获该匹配的子表达式,即他是一个非捕获匹配,不存在存储供以后使用的匹配。这对于用or字符(|)组合模式不见的情况很有用。例如,“industr(?:y|ies)是比’industry|industries’更经济的表达式 (?!pattern) 该表达式匹配不春雨匹配pattern的字符串的起始点的搜索字符串,它是一个捕获匹配。例如,“Windows(?=95|98|NT|2000)“匹配 “Windows 2000”中的“Windows”,但是不“Windows 3.1"中的”Windows”。 (?!pattern) 该表达式匹配不处于匹配 pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配,例如“Windows(?!95|98|NT|2000)“匹配”Windows 3.1"中的“Windows”,但不匹配“Windows3.1"向后的”Windows" 案例
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp08 { public static void main(String[] args) { String content = "hello韩顺平教育 jack韩顺平老师 韩顺平同学hello"; // String regStr = "韩顺平教育|韩顺平老师|韩顺平同学"; // 上面的写法可以等价非捕获分组 // (?:pattern) // String regStr = "韩顺平(?:教育|老师|同学)"; // 不建议这样写,因为这看似一个分组, // 但是并不会捕获分组,所以如果使用matcher.group(1)捕获会报错的 //(?!pattern) // String regStr = "韩顺平(?=教育|老师)"; // 非捕获,不能使用matcher.group(1)获取,或报错 //(?!pattern) String regStr = "韩顺平(?!教育|老师)"; //匹配不是韩顺平教育和韩顺平老师的韩顺平,是其他的韩顺平 非捕获,不能使用matcher.group(1)获取,或报错 // 创建模式对象 Pattern pattern = Pattern.compile(regStr); // 创建匹配器对象 Matcher matcher = pattern.matcher(content); // 循环遍历匹配到的字符并打印 while (matcher.find()) { System.out.println("找到:" + matcher.group(0)); } } }
取消贪婪匹配
- 可以在任意贪婪匹配符后面加上?可以取消贪婪匹配
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp09 { public static void main(String[] args) { String content = "hello111111 ok"; // String regStr = "\\d+"; // 默认时贪婪匹配 String regStr = "\\d+?"; // 在贪婪匹配的字符后面加一个?可以取消贪婪匹配 Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到:" + matcher.group(0)); } } }
应用案例
- 对字符串进行如下验证
汉字
邮政编码
要求:是1-9开头的六位数,比如:123890
qq号码
要求:是1-9开头的11位数,比如2693024032
手机号码
要求:必须是以13,14,15,18开头的11位数
URL:如图:https://www.bilibili.com/video/BV1Eq4y1E79W/?p=16&spm_id_from=pageDriver&vd_
代码:
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 正则表达式的应用实例 * */ public class Regexp10 { public static void main(String[] args) { // String content = "韩顺平教育"; // String content = "123890"; // String content = "2693024202"; // String content = "15216173555"; String content = "https://cwiki.apache.org/confluence/display/Hive//GettingStarted"; // 汉字 // String regStr = "^[\u0391-\uffe5]$"; // 表示在这个编码值内的字符就是汉字 // 邮政编码 // String regStr = "^[1-9]\\d{5}$"; //qq号码 //String regStr = "^[1-9]\\d{4,9}$"; // 手机号 // String regStr = "^1[3|4|5|8]\\d{9}$"; // url /* * 思路: * 1、想去顶url的开始部分 https:// | http:// * 2、然后通过 ([\w-]+\.)+[\w-]+匹配www.bilibili.com * 3、/video/BV1Eq4y1E79W/.... 匹配(\\/[\\w-?=&/@#.]*)?$ * */22 // 注意:[.] 表示匹配就是.本身 String regStr = "^((https|http)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/@#.]*)?$"; // 创建模式对象 Pattern pattern = Pattern.compile(regStr); // 创建匹配对象 Matcher matcher = pattern.matcher(content); // 获取到的匹配字符 if (matcher.find()) { System.out.println("满足格式"); System.out.println(matcher.group(0)); } else { System.out.println("不满足格式"); } // 这里如果使用Patternmatches 整体匹配比较简洁 System.out.println(Pattern.matches(regStr,content)); } }
.在中括号里面是不需要进行转义的,任何符号都是,不需要转义
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp11 { public static void main(String[] args) { String content = "hello abc hello"; // String regStr = "[.]]"; // 匹配字符. // String regStr = "."; // 匹配所有字符 String regStr = "?"; // 匹配单独的字符? Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到:" + matcher.group(0)); } } }
Pattern.matches方法的作用
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp11 { public static void main(String[] args) { String content = "hello abc hello"; // String regStr = "[.]]"; // 匹配字符. String regStr = "."; // 匹配所有字符 Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到:" + matcher.group(0)); } // 这里如果使用Patternmatches 整体匹配比较简洁 System.out.println(Pattern.matches(regStr,content)); } }
Matcher.start方法和Matcher.end方法的作用
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * Matcher 类的常用方法 * */ public class MatcherMathod { public static void main(String[] args) { String content = "hello edu jack tom hello hspedu 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("韩顺平教育"); // 如果想要替换原来字符串的话使用content接收 content = matcher.replaceAll("韩顺平教育"); //System.out.println("newContent="+ newContent); System.out.println("content=" + content); } }
分组、捕获、反向应用的关系
需求:
给你一段文本,请你找出所有四个数字连在一起的子串,并且这四个数字要满足①第一位与第四位相同②第2位于第3位相同,比如 1221,5775,…分组:
- 我们可以用圆括号组成一个比较复杂的匹配 模式,那么一个圆括号的部分我们可以看作是一个子表达式/一个分组。
捕获
- 把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里方便后面引用,从左向右,以分组的左括号为编制,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式
反向引用
- 圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用即可以是在正则表达式内部,也可以是在正则表达式外部,内部有反向引用\\分组号,外部反向引用$分组号
案例
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 反向引用 * */ public class Regexp12 { public static void main(String[] args) { String content = "h1234e9875llo33333 12321-333999111jack tom155111 jack22 yyy4343434 xxx"; // String regStr = "(\\d)\\1"; // String regStr = "(\\d)\\1{4}"; // tring regStr = "(\\d)(\\d)\\2\\1"; /* * 请在字符串中检索商品编号,形式如:12321-333999111 这样的号码, * 要求满足前面是一个五位数,然后一个-号,然后是一个九位数,连续的每三位要相同 * */ String regStr = "(\\d)(\\d)\\d\\2\\1-(\\d)\\3{2}(\\d)\\4{2}(\\d)\\5{2}"; Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到" + matcher.group(0)); } } }
案例使用反引用替换掉多于的字符
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; 5 public class Regexp13 { public static void main(String[] args) { String content = "我....我要....学学学学....编程java!"; // 1.首先去掉所有的. Pattern pattern = Pattern.compile("\\."); Matcher matcher = pattern.matcher(content); content = matcher.replaceAll(""); System.out.println("content=" + content); // 2.去掉重复的字 我我要学学学学编程java! // 思路 // (1) 使用 (.)\\+ // (2) 使用反向引用$1 来替换匹配到的内容 // 注意:因为正则表达式变化,所以需要重置matcher pattern = Pattern.compile("(.)\\1+"); matcher = pattern.matcher(content); while (matcher.find()) { System.out.println("找到=" + matcher.group(0)); } System.out.println("---------------"); // 使用反向引用$1来替换正则表达式说匹配到的所有字符 String contern = matcher.replaceAll("$1"); System.out.println("content" + contern); // 3.使用一条语句 取去掉重复的文字我我要学学学学编程java! Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1"); System.out.println("content" + contern); } }
案例
package cn.itcast.regexp; public class Regexp14 { public static void main(String[] args) { String content = "在2000年5月,JDK1.3, JDK1.4和J2SE1。3款已经发布,几周后的\n" + "赢得了苹果Mac OSX工业标准的支持。2001年9月24日,J2EE1。三个头发\n" + "2002年2月26日,J2SE1.4. 因为Java的计算能力已经提高了\n"; // 使用正则表达式方式,将JDK1.3 和 JDK1.4 替换成JDK content.replaceAll("JDK1\\.3|JDK1\\.4", "JDK"); // 要求 验证一个手机号,要求必须是以138 139 开头的 content = "13883739455"; if (content.matches("1(38|39)\\d{8}")) { System.out.println("验证成功"); } else { System.out.println("验证失败"); } //要求按照 # 或者 -或者 ~ 或者 数字 来分割 content = "hello#abc-jack12smith~北京"; String[] split = content.split("#|-|~"); for(String s:split){ System.out.print(s+"\t"); } } }
案例
package cn.itcast.regexp; public class Regexp15{ public static void main(String[] args) { /* * 规定电子邮件规则为 * 1、只有一个@ * 2、@前面是用户名,可以是a-z A-Z 0-9 _ -字符 * 3、@后面是域名,并且域名只能是英文字母,比如 sohu.com 或者tsinghua.org.cn * 4、写出对应的正则表达式,验证输入的字符串是否为满足的规则 * */ String content = "hsp@shu.com"; String regStr = "^[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+"; // 1.String 的 matches 是整体匹配 if(content.matches(regStr)){ System.out.println("匹配成功"); }else{ System.out.println("匹配失败"); } } }
package cn.itcast.regexp; public class Homework02 { public static void main(String[] args) { // 要求验证是不是整数或者小数 // 提示:这个题要考虑正数和负数 // 比如:123 -345 34.89 -87.9 -0.01 0.45 等 /* * 1.先写出简单的正则表达式 * 2.在逐步的完善[根据各种情况来完善] * */ String content = "37874554545454455454"; String regStr = "^[-+]?([1-9]\\d*|0)(\\.)?(\\d+)?$"; if(content.matches(regStr)){ System.out.println("匹配成功 是整数或者小数"); }else{ System.out.println("匹配失败"); } } }
package cn.itcast.regexp; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regexp16 { public static void main(String[] args) { String content = "http://www.sohu.com:8080/abcfd/dfd/fdf//fd/index.heml"; String regStr = "^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$"; Pattern pattern = Pattern.compile(regStr); Matcher matcher = pattern.matcher(content); if (matcher.matches()) { // 整体匹配,如果匹配成功,可以通过group(x),获取对应分组的内容 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("文件:" + matcher.group(4)); } else { System.out.println("匹配失败"); } } }