一、正则表达式
- 概述
- 正则表达式定义了字符串的模式。
- 正则表达式可以用来搜索、编辑或处理文本。
- 正则表达式定义了字符串的模式,可以用来 搜索, 编辑 , 处理问题,还可以做数据提取操作
- 不仅限于某一种语言,但是在每种语言中有细微的差别
- java中 1.4推出,java.util.regex 包下
- 在java中 使用\转移符,把有意义字符转换为无意义字符
- 但是在正则表达式中,\也是转移符,所以如果我们再java中写正则表达式的转移符的话,要写两个\\
- 语法
- 常用语法 :
- \ 转移符
- . 匹配任意字符
- 取值范围 :
- [abc] : 可能是a,也可能是b,也可能是c
- [^abc] : 不是a,b,c任意一个
- [a-zA-Z ]: 匹配大小写 字母
- [^a-zA-Z ] : 非大小写字母
- [0-9] : 数字
- [a-zA-Z0-9] : 大小写字母和数字
- 简洁表示 :
- . : 任意字符
- \d : 表示数字[0-9]
- \D : 表示非数字 [^0-9]
- \s : 表示由空字符组成
- \S : 表示由非空字符组成
- \w : 表示 字母,数字,下划线 [a-zA-Z0-9_]
- \W : 表示非 字母,数字,下划线 [^a-zA-Z0-9_]
- 数量相关 :
- ? : 表示出现0或1次
- + : 表示出现1次或多次 count >=1
- * : 表示出现0次或0次以上 count >= 0
- {n} : 表示出现n次
- {n,} : 表示出现n次及n次以上 count >= n
- {n,m} : 表示出现n到m次 m>=count>=n
- 常用语法 :
- (),[],{}
-
小括号():匹配小括号内的字符串,可以是一个,也可以是多个,常跟“|”(或)符号搭配使用,是多选结构的
-
string name = "way2014"; regex:(way|zgw) result:结果是可以匹配出way的,因为是多选结构,小括号是匹配字符串的
-
string text = "123456789"; regex:(0-9) result:结果是什么都匹配不到的,它只匹配字符串"0-9"而不是匹配数字, [0-9]这个字符组才是匹配0-9的数字
-
-
中括号[]:匹配字符组内的字符,比如咱们常用的[0-9a-zA-Z.*?!]等,在[]内的字符都是字符,不是元字符,比如“0-9”、“a-z”这中间的“-”就是连接符号,表示范围的元字符,如果写成[-!?*(]这样的话,就是普通字符
-
string text = "1234567890"; regex:[0-9] result:结果是可以匹配出字符串text内的任意数字了,像上边的【或符号“|”在字符组内就是一个普通字符】
-
string text = "a|e|s|v"; regex:[a|e|s] result:结果就是匹配字符a、e、s三个字符,这个跟(a|e|s)有区别的,区别就是(a|e|s)匹配的是a、e、s三个字符的随意一个,三个 中的任意一个,这里|是元字符
-
-
匹配次数,匹配在它之前表达式匹配出来的元素出现的次数,{n}出现n次、{n,}匹配最少出现n次、{n,m}匹配最少出现n次,最多出现m次
-
- 练习
- 匹配整数和小数
-
\d 数字
-
. 任意字符
-
/ 转义
-
+ 1次或多次
-
? 0次或1次
-
() 把\.和\d+看做整体
-
\d+(\.\d+)?
-
- 电话
-
\d{11}
^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$
-
- 匹配正整数
-
[1-9][0-9]*
-
- 非负整数
- 整数
-
(-?[1-9]\\d*)|0
-
- 匹配整数和小数
二、Java中正则表达式
在java中 正则表达式封装为三个相关的类
PatternSyntaxException : 异常类
Pattern : 正则表达式对象,能做一些简单操作
Matcher : 支持强大的正则表达式
- Pattern
- 概述
- 用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建
- 可以通过Pattern.complie(String regex)创建一个正则表达式
- 只能做一些简单的匹配操作
- 使用
- Pattern : 很多时候我们直接使用String中的三个方法即可
验证 : 校验操作,boolean matches(String regex)
拆分 : String[] split(String regex)
替换 : String replaceAll(String regex,String replace) -
public static void main(String[] args) { // test1(); test2(); } // 校验 public static void test2(){ String regex = "(-?[1-9]\\d*)|0"; String str = "-123"; // 全词匹配,静态方法 boolean flag = Pattern.matches(regex, str); System.out.println(flag); // String中的方法 System.out.println(str.matches(regex)); } // 拆分 public static void test1(){ String str = "1,2,3,4,5"; // 创建正则表达式对 Pattern pattern = Pattern.compile(","); // 拆分方法 String[] strs = pattern.split(str); for (String string : strs) { System.out.println(string); } System.out.println("========="); strs = str.split(","); for (String string : strs) { System.out.println(string); } }
- Pattern : 很多时候我们直接使用String中的三个方法即可
- 概述
- Matcher
- 概述
- 构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例 Matcher m = p.matcher("aaaaab");
- 支持便捷强大的正则匹配操作,包括分组、多次匹配支持
- 三大方法
-
Matcher.matches():对整个字符串进行匹配,只有整个字符串都匹配了才返回true
-
Matcher.lookingAt():对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
-
Matcher.find():对字符串进行匹配,匹配到的字符串可以在任何位置
-
- 字符串匹配模式
-
public static void main(String[] args) { // 整数规则 String regex = "(-?[1-9]\\d*)|0"; // 需要校验的字符串 String input = "12.12"; // 引擎对象 Pattern pattern = Pattern.compile(regex); // 匹配器对象 Matcher matcher = pattern.matcher(input); /** * 三种匹配模式 * matches : 全词匹配 123 * find : 任意位置均可 asd123das * lookingAt : 从前向后,前面是就可以 123sadasd */ // false System.out.println(matcher.matches()); // 不要连着使用,每次使用 都重新打开一个 matcher对象即可 // find可以调用多次,因为find适合做一些提取操作 matcher = pattern.matcher(input); System.out.println(matcher.find()); System.out.println(matcher.find()); System.out.println(matcher.find()); matcher = pattern.matcher(input); System.out.println(matcher.lookingAt()); }
-
- 数据提取
-
public static void main(String[] args) { // 整数规则 // [\u4e00-\u9fa5] 汉字范围 // 一个小括号 就是一组 String regex = "([\u4e00-\u9fa5]{2,3})电话号码是(\\d{11})"; // 需要校验的字符串 String input = "asd小明电话号码是13113113111sass张小黑电话号码是15115115111"; // 引擎对象 Pattern pattern = Pattern.compile(regex); // 匹配器对象 Matcher matcher = pattern.matcher(input); /** * find和group 结合使用 可以完成数据提取 */ // 想要获取下一个匹配的数据,只需要再次调用find即可 // 如果find为false,说明后面没有符合条件的数据了 while (matcher.find()) { // 0或者无参 都是获取匹配到的整个数据 // 1 就是第一组 , 2 就是第二组 System.out.println(matcher.group(0)); System.out.println(matcher.group(1)); System.out.println(matcher.group(2)); } }
-
- 叠词去重
- 叠词去重
我我...我我...我要..要要...要要...学学学..学学...编编编编....编程..程....程程程程..程.
转换为我要学编程
1 只留下汉字,其余字符去掉
2 把重复数据分为两组 , 比如 1111,分为 1 和 111
3 使用 1 把 1111 替换 -
public static void main(String[] args) { String string = "我我......我要..要要...要要...学学学..学学...编编编编....编程..程....程程程程..程."; // 1 先把.去掉 // string = string.replaceAll("\\.", ""); string = string.replaceAll("[^\u4e00-\u9fa5]", ""); // ((我)(我我我我))(要)(要要要要)学学学学学编编编编编程程程程程程程 System.out.println(string); // (.) : 任意字符 // \\1 捕获1次,获取指定组的数据, //1就是第一组的数据,//2就是第二组的数据 // (\\d)\\1 : 表示连续出现两个字符 , 11,22,33,44 // (\\d)(a)\\1 : 第一个是数字,第二个是a,第三个和第一个相同 1a1,2a2,3a3 // (\\d)(a)\\2 : 第一个是数字,第二是a,第三个和第二个一样,也是a,1aa,2aa,3aa String regex = "(.)(\\1+)"; // Pattern pattern = Pattern.compile(regex); // Matcher matcher = pattern.matcher(string); // while (matcher.find()) { // // System.out.println(matcher.group(0)); // // System.out.println(matcher.group(1)); // // System.out.println(matcher.group(2)); // string = string.replaceAll(matcher.group(0), matcher.group(1)); // } // System.out.println(string); // $1 就等于 matcher.group(1) string = string.replaceAll(regex, "$1"); System.out.println(string); }
- 叠词去重
- 概述