正则表达式
正则表达式
(一). 理论
1.1 定义:正则表达式是用来操作字符串数据的,通过一些特定的符号来体现。从字面理解可以理解为:用正确的规则来表达字符串数据
1.2 常用符号(必须要牢记)
- 字符类
[abc]————代表字符串上的某一位只能是a或b或c
[^abc]————任何字符,除了a、b、c(表否定的)
[a-zA-Z]————代表a到z或A到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,而非m到p:[a-lq-z](减去)
- 预定义字符类
. 任何字符
\d————数字[0-9]
\D————非数字:[^0-9]
\w————单词字符:[a-zA-Z_0-9]
\W————非单词字符:[^\w]
\s————空白字符:[ \t\n\x0B\f\r]
\S————非空白字符:[^\s] - 边界匹配器
^————行的开头
$————行的结尾
\b————单词边界
\B————非单词边界
\A————输入的开头
\Z————输入的结尾,仅用于最后的结束符(如果有的话)
\z————输入的结尾
\G————上一个匹配的结尾 - Greedy数量词
X?————X,一次或一次也没有
X*————X,零次或多次
X+————X,一次或多次
X{n}————X,恰好n次
X{n,}————X,至少n次 - X{n,m}————X,至少n次,但不超过m
(二). 上代码
正则表达式的功能
- 匹配
- 切割
- 替换
- 获取
2.1 匹配功能
代码演示
1 public class RegexDemo { 2 public static void main(String[] args) { 3 functionDemo_1(); 4 } 5 /* 6 * 1.匹配 其实使用的就是String类中的matches()方法 7 * 演示匹配 8 */ 9 public static void functionDemo_1(){ 10 //手机号码 11 String tel = "15863350430"; 12 //定义正则规则 13 // String regex = "1[358][0-9]{9}";//{}代表的是次数 14 String regex = "1[358]\\d{9}";//\d是代表[0-9],但是在字符串中要将\进行转义所以在字符串中\\d代表[0-9] 15 Boolean b = tel.matches(regex); 16 System.out.println(tel + ":" + b); 17 } 18 }
2.2 切割功能:
代码演示
1 public class RegexDemo { 2 public static void main(String[] args) { 3 /* 4 * 正则表达式 5 * 2.切割 6 * 其实使用的就是String类中的split()方法 7 */ 8 // functionDemo_1(); 9 functionDemo_2(); 10 } 11 /*2.切割 12 * 其实使用的就是String类中的split()方法 13 */ 14 public static void functionDemo_2() { 15 //空格一次时候 16 // String str = "zhangsan lisi wangwu"; 17 // String[] names = str.split(" "); 18 //空格多次时候 19 // String str = "zhangsan lisi wangwu"; 20 // String[] names = str.split(" +"); 21 //当用多次叠词的时候 22 String str = "zhangsantttttlismmmmwangwu";//在正则中的复用的封装方式 用()封装, 23 // 封装后自动进行编号,写1就是1编号,叫1组;写2就是2编号,叫2组。直接用编号就是拿组 24 String[] names = str.split("(.)\\1+");//将数字1转义为组标号。假设没有写括号,默认为第0组 25 for(String name : names){ 26 System.out.println(name); 27 } 28 } 29 }
在此补充一下 组 的概念:
- (X)————X,作为捕获组
- \n————引用捕获组
- 捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
- 组1 ((A) (B(C)))
- 组2 (A)
- 组3 (B(C))
- 组4 (C)
- 注意:组零始终代表整个表达式。当没有括号时默认正则表达式为组零
2.3 替换功能
代码演示
1 public class RegexDemo { 2 3 public static void main(String[] args) { 4 /* 5 * 正则表达式 6 * 3.替换 7 * 其实使用的就是String类中的replaceAll()方法 8 */ 9 // functionDemo_1(); 10 // functionDemo_2(); 11 functionDemo_3(); 12 } 13 public static void functionDemo_3() { 14 String str = "zhangsantttttlismmmmwangwu"; 15 // String newStr = str.replaceAll("(.)\\1+", "#");//.代表任意字符 16 String newStr = str.replaceAll("(.)\\1+", "$1");//正则中$,用美元符号$拿取第一个参数中的组标号 17 System.out.println(newStr); 18 19 String tel = "15800001111"; 20 String newtel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");//此处时将电话号码前三位封装成组,后四位封装成组,在第二个参数中用$符号来获取第一个参数中的组达到替换效果
21 System.out.println(newtel); 22 } 23 }
运行结果
zhangsantlismwangwu
158****1111 //此处在很多方面都会应用到,譬如电话号码中间几位隐藏,以及银行卡号中间几位隐藏,原理都是一样的
2.4 获取功能
代码演示
1 import java.util.regex.Matcher; 2 import java.util.regex.Pattern; 3 4 public class RegexDemo { 5 public static void main(String[] args) { 6 functionDemo_4(); 7 } 8 9 /* 10 * 获取: 11 * 将正则规则进行对象的封装 12 * Pattern p = Pattern.compile("a*b"); 13 * 通过正则对象的matcher方法与字符串相关联,获取要对字符串操作的匹配器对象,matcher 14 * Matcher m = p.matcher("aaaaab"); 15 * 通过matcher匹配器对象的方法对字符串进行操作 16 * boolean b = m.matches(); 17 */ 18 public static void functionDemo_4() { 19 String str = "da jia hao,hen gao xing ren shi ni!"; 20 String regex = "\\b[a-z]{3}\\b";//\\b是单词边界 21 //将正则规则进行对象的封装 22 Pattern p = Pattern.compile(regex); 23 //通过正则对象的matcher方法与字符串相关联,获取操作字符串的匹配器对象 24 Matcher m = p.matcher(str); 25 //通过Matcher匹配器对象对字符串进行操作 26 boolean b = m.matches(); 27 System.out.println(b); 28 while(m.find()){ 29 System.out.println(m.group());//获取匹配的子序列 30 System.out.println(m.start()+":"+m.end()); 31 } 32 } 33 }
(三). 实践
需求1:治疗口吃:我我.我...我我要要...要要要要..要要学学..学学..学学学.学编编编.编编..编编编编程..程程.程程
代码演示
1 public class RegexTest { 2 3 public static void main(String[] args) { 4 //1. 5 //首先要用空串替换掉. 6 String str = "我我.我...我我要要...要要要要..要要学学..学学..学学学.学编编编.编编..编编编编程..程程.程程"; 7 str = str.replaceAll("\\.+", ""); 8 //其次要把叠词取消 9 str = str.replaceAll("(.)\\1+", "$1"); 10 System.out.println(str); 11 } 12 }
运行结果:
我要学编程
需求2:ip地址排序 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55
代码演示
1 import java.util.TreeSet; 2 3 public class RegexTest { 4 public static void main(String[] args) { 5 String ip_str = "192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55"; 6 //为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同,所以要补0,按照每位最多0进行补 7 ip_str = ip_str.replaceAll("(\\d+)", "00$1"); 8 //然后,每一段保留3位数字 9 ip_str = ip_str.replaceAll("0*(\\d{3})", "$1"); 10 //按照空格分割 11 String[] ips = ip_str.split(" +"); 12 TreeSet<String> ts = new TreeSet<String>();//按照字符串顺序排序 13 for(String ip : ips){ 14 ts.add(ip); 15 } 16 //输出 17 for(String ip : ts){ 18 System.out.println(ip.replaceAll("0*(\\d)", "$1")); 19 } 20 } 21 }
需求3:邮箱校验
代码演示
1 public class RegexTest { 2 3 public static void main(String[] args) { 4 RegexFunction_3(); 5 } 6 7 public static void RegexFunction_3() { 8 //3. 9 //邮箱校验:mbcd1@sina.com 10 String str = "mbcd1@sina.com.cn"; 11 // String regex = "[a-zA-Z_0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+"; 12 String regex = "\\w+@\\w+(\\.\\w{1,3})+";// \w 代表单词字符 表示[a-zA-Z_0-9] 13 boolean b = str.matches(regex); 14 System.out.println(str + ":"+ b); 15 16 } 17 }
以上内容就是常用的正则表达式的操作,多学多练,常用符号要多记!谢谢
勤能补拙是良训,一分辛苦一分才!我们一起努力!