学透~-~正则表达式~-~


前言

1.一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用,不过,经过练习后,就觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成
2.这里要特别强调,正则表达式不是只有java才有,实际上很多编程语言都支持正则表达式进行字符串操作!如图所示。


一、 正则表达式语法

1.0基本介绍

如果要想灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
1.限定符
2.选择匹配符
3.分组组合和反向引用符
4. 特殊字符
5.字符匹配符
6.定位符

1.1 元字符(Metacharacter)

1.11 转义号 \\

\ \符号 说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,否则检索不到结果,甚至会报错。
提示:在JAVA的正则表达式中,两个\\代表其他语言中的一个\。

🏃注意:需要用到转义符号有一下:. * () $ / \ [ ] ^ { }

代码如下(示例):

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp02 {
    public static void main(String[] args) {
        String content="ab.c$(a.bc(123(";
        //匹配(=>\\(
        //匹配.=>\\.,否则.表示匹配所有的字符
        //String reStr="\\(";
        //String reStr="\\.";
        //String reStr="\\d\\d\\d";
        String reStr="\\d{3}";
        Pattern pattern= Pattern.compile(reStr);
        Matcher matcher=pattern.matcher(content);
        while (matcher.find()) {

            System.out.println("找到"+matcher.group(0));
        }
    }
}

1.12 字符匹配符
符号含义示例解释
[]可接收的字符列表[efgd]e、f、g、h中的任意1个字符
[^]不接收的字符列表[^abc]除a、b、c之外的任意1个字符,包括数字和特殊符号
-连字符A-Z任意单个大写字母
.匹配除\n以外的任何字符a…b以a开头,b结尾,中间包括2个任意字符的长度为4的字符串,eg:aaab,aefb、a35b、a#*b
\\d匹配单个数字字符,相当于[0-9]\\d{3}(\\d)?包含31个或4个数字的字符串eg:123、9876
\\Dp匹配单个非数字字符,相当于[^0-9]\\D(\\d)*以单个非数字字符开头,后接任意个数字字符串eg:a、A342
\\w匹配单个数字、大小写字母字符相当于[0-9a-zA-Z]\\d{3}\\w以3个数字字符开头的长度为7的数字字母字符串eg:234abcd、12345Pe
\\W匹配单个非数字、大小写字母字符相当于[0-9a-zA-Z]\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串eg:#29、#?@10

光看这个是不太行的喔!上代码(建议各位小宝贝自己动手打一遍!!!)

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*演示字符匹配符的使用*/
public class RegExp03 {
    public static void main(String[] args) {
      String content="abc11c_8abc\nABCy    @";
       //        String regStr="[a-z]";//匹配a-z之间的任意一个字符
        //       String regStr="[A-Z]";//匹配A-Z之间的任意一个字符
        //       String regStr="abc";//匹配 abc字符串(默认区分大小写)
        //       String regStr="(?i)abc";//匹配 abc字符串(不区分大小写)
        //        说明:1.当创建Pattern对象时,指定 Pattern.CASE_INSENSITIVE,表示匹配是不区分字母大小写。
        //        Pattern pattern=Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
        //        String regStr="[0-9]";//匹配0-9之间的任意一个字符
        //        String regStr="[^a-z]";//匹配不在a-z之间任意一个字符
        //        String regStr="[^0-9]";//匹配不在0-9之间任意一个字符
        //        String regStr="[abcd]";//匹配在abcd中的任意字符
        //        String regStr="\\D";//匹配不在0-9之间任意一个字符
        //        String regStr="\\w";//匹配 大小写英字,下划线 文字母,数
         //       String regStr="\\s";//匹配任何空白字符(空格,制表符等)
        //        String regStr="\\S";//匹配非任何空白字符
        String regStr=".";//匹配\n之外的所有字符,如果要匹配.本身则需要使用\\.
        Pattern pattern=Pattern.compile(regStr);
        Matcher matcher=pattern.matcher(content);
        while (matcher.find()) {

            System.out.println("找到 "+matcher.group(0));
        }

    }
}

1.13选择匹配符

在匹配某个字符串的时候是选择性,即:既可以匹配这个,又可以匹配那个,这时你需要用到 选择匹配符 |

//例如:
public class RegExp04 {
public static void main(String[] args) {
	String content="liudehua 牛 流水";
	String regStr="liu|牛|流";
	Pattern pattern = Pattern.compile(regStr/*, 		Pattern.CASE_INSENSITIVE*/);
	Matcher matcher = pattern.matcher(content);
	while (matcher.find()) {
		System.out.println("找到 " + matcher.group(0));
	}
  }
}
1.14 限定符

限定符:用于指定其前面的字符和组合项连续出现多少次。

符号含义示例说明匹配输入
*指定字符重复0次或n次(无要求)零到多(abc)*仅包含任意个abc的字符串,等效于\w*abc/abcabcabc
+指定字符重复1次或n次(至少1次)m+(abc)*以至少1个m开头,后接任意个abc的字符串m、 mabc、mabcabc
?指定字符重复0次或1次(最多一次)0到1m+abc?以至少1个m开头,后接ab或者abc的字符串mab,mabc,mmmab,mmabc
{n}只输入n个字符[abcd]{3}由abcd中字母组成的任意长度为3的字符串abc,dbc,adc
{n,}指定匹配至少n个匹配[abcd]{3,}由abcd中字母组成的任意长度不小于3的字符串aab,dbc,aaabdc
{n,m}指定至少n个但不多于m个匹配[abcd]{3,5}由abcd中字母组成的任意长度不小于3不大于5的字符串abc,abcd,aaaaa,bcdab
package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExp05 {
    public static void main(String[] args) {
        String content="a11111111aaaaaahello";
//        String regStr="a{3}";// 表示匹配 aaa
//        String regStr="1{3}";// 表示匹配 111
//        String regStr="\\d{2}";// 表示匹配 两位的任意数字字符
//     a{3,4},1{4,5},\\d{2,5}
        //细节:java匹配默认贪婪匹配,即尽可能匹配多的
//        String regStr="a{3,4}";// 表示匹配 aaaa
//        String regStr="1{4,5}";// 表示匹配 1111或11111
//        String regStr="\\d{2,5}";// 表示匹配 两位数或者3,4,5
        //1+
//        String regStr="1+";//表示匹配1个1或者多个1
        //1*
//        String regStr="1*";//表示匹配0个1或者多个1
        //演示?的使用,遵循贪婪匹配
        String regStr="a1?";//匹配a或者a1
        Pattern pattern=Pattern.compile(regStr);
        Matcher matcher=pattern.matcher(content);
        while (matcher.find()) {

            System.out.println("找到 "+matcher.group(0));
        }
    }
}

1.15定位符

定位符:规定要匹配的字符出现的位置,比如在字符串的开始还是结束的位置。必须掌握

符号含义示例说明匹配输入
^指定起始字符^ [0-9]+[a-z]*以至少1个数字开头,后接任意个小写字母的字符串123、6aa、555edf
\\b匹配目标字符串的边界han\\b这里说的字符串边界指的是子串间有空格,或者目标字符串的结束位置hanshunping sphan nnhan
\\B匹配目标字符串的非边界han\\B和\\b的含义刚刚相反hangshunping sphan nnhan
package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*演示定位符*/
public class RegExp06 {
    public static void main(String[] args) {
//        String content="123abc";
          String content="hanshunping aphan nnhan";
        //以至少1个数字开头,后接任意个小写字母的字符串
//        String regStr="^[0-9]+[a-z]*";
        //以至少1个数字开头,必须以至少一个小写字母结束($)
//        String regStr="^[0-9]+\\-[a-z]+$";
        //表示匹配边界的han[这里的边界是指:被匹配字符串最后,
        //也可以是空格的子字符串的后面
//        String regStr="han\\b";
//        和\\b的含义相反
        String regStr="han\\B";//第一个han
        Pattern pattern=Pattern.compile(regStr);
        Matcher matcher= pattern.matcher(content);
        while(matcher.find()){
            System.out.println("找到="+matcher.group(0));
        }


    }
}

1.16 分组
常用分组构造形式说明
(pattern)非命名捕获。捕获匹配的子字符串。编号为0的第一个捕获是由整个正则表达式模式匹配的文本,其它捕获结果则根据左括号的顺序从1开始自动编号
(?pattern)命名捕获,将匹配的字符串捕获到一个组名称或编号名称中,用于name的字符串,不能包含任何标点字符,并且不能以数字开头,可以使用单引号替代尖括号,例如(?‘name’)
(?:pattern)匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配,这对于用“or"字符(|)组合模式部件的情况很有用。例如:‘industr(?y|ies)是比’industry|industries’更经济的表达式
(?=pattern)它是一个非捕获匹配。例如:‘Windows(?=95|NT|2000)'匹配”Windows 2000"中的“WIndows",但不匹配”Windows 3.1"中的“WIndows"
(?pattern)该表达式匹配不处于匹配patten的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如,‘Windows(?!95|NT|2000)'匹配”Windows 3.1"中的“WIndows",但不匹配”Windows 2000"中的“WIndows"
package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*分组*/
public class RegExp07 {
    public static void main(String[] args) {
        String content="hanshunping s7789 nn1189han";
        //下面就是非命名分组
        /* 说明*/
        //1.matcher.group(0) 得到匹配到的字符串
        //2.matcher.group(1) 得到匹配到的字符串的第1个分组内容
        //3.matcher.group(2)   得到匹配到的字符串的第2个分组内容
       // String reStr="(\\d\\d)(\\d\\d)";
        //命名分组:即可以给分组取名?<name>
        String reStr="(?<g1>\\d\\d)(?<g2>\\d\\d)";
        Pattern pattern=Pattern.compile(reStr);
        Matcher matcher=pattern.matcher(content);
        while(matcher.find()){
            System.out.println("找到"+matcher.group(0));
            System.out.println("第1个分组内容="+matcher.group(1));
            System.out.println("第1个分组内容[通过组名]="+matcher.group(("g1")));
            System.out.println("第2个分组内容="+matcher.group(2));
            System.out.println("第2个分组内容[通过组名]="+matcher.group(("g2")));
        }

    }
}

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**演示非捕获分组,语法比较奇怪*/
public class RegExp08 {
    public static void main(String[] args) {
        String content="hello新东方教育 john新东方老师 新东方同学hello";
        //找到 新东方教育、新东方老师、新东方同学 子字符串
       // String regStr="新东方教育|新东方老师|新东方同学";
        //等价于非捕获分组,注意:不能 matcher.group(1)
      //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));
            //System.out.println("找到:"+matcher.group(1));
        }
    }
}

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**非贪婪匹配*/
public class RegExp09 {
    public static void main(String[] args) {
        String content="hello11111 ok";
        //String regStr="\\d+";//默认是贪婪匹配
        String regStr="\\d+?";//非贪婪匹配 ?表示1到多
        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));
        }
    }
}

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReExp10 {
    public static void main(String[] args) {
       //汉字
        String content="13588889999";
        //String regStr="^[\u0391-\uffe5]+$";
        //邮政编码 要求:是1-9开头的一个六位数,比如:123890
       // String regStr="^[1-9]\\d{5}$";
        //QQ号码
        //要求:是1-9开头的一个(5-10位数)
        //12389,1345687
        //String regStr="^[1-9]\\d{4,9}$";
        //手机号
        //要求:必须13,14,15,18 开头的11位数,比如13588889999
       String regStr="^1[3|4|5|8]\\d{9}$";
        Pattern pattern=Pattern.compile(regStr);
        Matcher matcher= pattern.matcher(content);
        if(matcher.find()){
            //System.out.println(matcher.group(0));
            System.out.println("满足格式");
        }else{
            System.out.println("不满足格式");
        }
        //邮政编码

    }
}

1.17 分组、捕获、 反向引用

1.分组
我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看作是一个子表达式/一个分组
2.捕获
把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里,方便后面引用,从左到右,以分组的左括号为标志,第一个出现的分组的组好为1,第二个为2,以此类推,组0代表的是这个正则表达式。
3.反向引用
圆括号的内容被捕获后,可以在这个括号后使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\分组号,外部反向引用$分组号。

package 正则表达式;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

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) 使用 (.)\\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);
    }
}

1.18 String 类中使用正则表达式
public class StringReg {
    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);
//要求 验证一个 手机号, 要求必须是以 138 139 开头的
        content = "13888889999";
        if (content.matches("1(38|39)\\d{8}")) {
            System.out.println("验证成功");
        } else {
            System.out.println("验证失败");
        }
      
//要求按照 # 或者 - 或者 ~ 或者 数字 来分割
        System.out.println("===================");
        content = "hello#abc-jack12smith~北京";
        String[] split = content.split("#|-|~|\\d+");
        for (String s : split) {
            System.out.println(s);
        }

    }
}

总结

提示:这里对文章进行总结:
以上就是正则表达式的基本知识点和内容,希望大家可以好好消化一下,如果你觉得还有补充的,请在评论区留言,欢迎大家来指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值