11Java正则表达式学习笔记

            Java正则表达式学习笔记

文章目录

  • 1 Java正则表达式简介
    • 1.1 快速入门
    • 1.2 基本介绍
  • 2 三个常用类
    • 2.1 Pattern
      • 2.1.1 Pattern.compile(regStr)
      • 2.1.2 Pattern.matches(regStr, content)
    • 2.2 Matcher
      • 2.2.1 matcher.find()
      • 2.2.2 matcher.matches()
      • 2.2.3 matcher.replaceAll("")
    • 2.3 PatternSyntaxExcepiton
  • 3 基本语法
    • 3.1 转义符号
    • 3.2 字符匹配符
    • 3.3 选择匹配符 |
    • 3.4 限定符
    • 3.5 定位符
    • 3.6 非贪婪匹配
    • 3.7 分组
    • 3.8 捕获
    • 3.9 反向引用
  • 4 String类中使用正则表达式
    • 4.1 替换功能
    • 4.2 判断功能
    • 4.3 分隔功能
  • 5 应用实例
    • 5.1 验证电子邮件格式是否合法
    • 5.2 要求验证是不是整数或者小数
    • 5.3 对一个url进行解析
  • 6 常用Java正则表达式

1 Java正则表达式简介

1.1 快速入门

为什么要学习正则表达式

。极速体验正则表达式威力

​ 1.提取文章中所有的英文单词

​ 2.提取文章中所有的数字

​ 3.提取文章中所有的英文单词和数字

​ 4.验证电子邮件

​ 5.验证手机号

解决之道-正则表达式

1.为了解决上述问题,Java提供了正则表达式技术,专门用于处理类似文本问题

2.简单的说:正则表达式是对字符串执行模式匹配的技术

3.正则表达式:regular expression == regexp

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:快速体验正则表达式
 * 作者:汤观林
 * 日期:2022年01月10日 20时
 */
public class RegexpTest1 {
    public static void main(String[] args) {

        String context = "1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页能够“灵活”起来,急需一种软件技术来开发一种程序," +
                "这种程序可以通过网络传播并且能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物力和财力。这个时候," +
                "Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的试验平台,由于它是按照嵌入式系统硬件平台体系结构进行编写的," +
                "所以非常小,特别适用于网络上的传输系统,而Oak也是一种精简的语言,程序非常小,适合在网络上传输。Sun公司首先推出了可以嵌入网页" +
                "并且可以随同网页在网络上传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术),并将Oak更名为Java(在申请注册商标时," +
                "发现Oak已经被人使用了,再想了一系列名字之后,最终,使用了提议者在喝一杯Java咖啡时无意提到的Java词语)。" +
                "5月23日,Sun公司在Sun world会议上正式发布Java和HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape和" +
                "微软等各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证,并为自己的产品开发了相应的Java平台";

          //1 提取文章中所有的英文单词
          //  提取文章中所有的数字
         // 提取文章中所有的英文单词和数字
         //提取百度热榜 标题

        //传统方法:遍历方式  代码量大  效率不高
        //正则表达式方式
            //1.1 先创建一个Pattern对象,模式对象,可以理解成就是一个正则表达式对象
            Pattern pattern1 = Pattern.compile("[a-zA-Z]+");
            Pattern pattern2 = Pattern.compile("[1-9]+");
            Pattern pattern3 = Pattern.compile("([1-9]+)|([a-zA-Z]+)");
            //1.2 再创建一个匹配器对象
            //理解:就是matcher匹配器按照pattern模式,到content文本中去匹配
            Matcher matcher = pattern3.matcher(context);
            //1.3 可以开始循环匹配
            while (matcher.find()){
              //匹配内容,文本,放到m.group(0)
                System.out.println("找到:"+matcher.group(0));
            }
    }
}

运行结果:

找到:1995
找到:Oak
找到:IT
找到:Sun
找到:Oak
找到:Oak
...
找到:HP
找到:Oracle
找到:Netscape
找到:Java
找到:Java

结论:

正则表达式-------文本处理的利器

​ 大数据清洗数据

​ JDK的String类可以直接使用正则表达式

1.2 基本介绍

1.一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用。

不过,经过练习后,就觉得这些复杂的表达式写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的

文本处理工作压缩在几分钟(甚至几秒钟)内完成。

2.老韩这里要强调,正则表达式不是只有Java才有,实际上很多编程语言都支持正则表达式进行字符串操作。

​ 比如java,javascript,php。我们这里讲的是Java正则表达式。

2 三个常用类

2.1 Pattern

Pattern对象时一个正则表达式对象,Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,

​ 它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数,

比如:Pattern pattertn = Pattern.compile(pattertn);

2.1.1 Pattern.compile(regStr)

生成表达式对象

String regStr1 = "\\d+?";  
Pattern pattern = Pattern.compile(regStr1);   //生成表达式对象

2.1.2 Pattern.matches(regStr, content)

整体匹配

boolean flag = Pattern.matches(regStr5, content5);

代码:

package com.tangguanlin.regexp;
import java.util.regex.Pattern;
/**
 * 说明:Pattern的matches方法,用于整体匹配,在验证输入的字符串是否满足条件使用
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest10 {
    public static void main(String[] args) {

        String content5  = "hello abc hello,韩顺平教育";
        String regStr5 = "hello";
        boolean flag = Pattern.matches(regStr5, content5);  //整体匹配
        if (flag){
                    System.out.println("整体匹配");
        }else {
            System.out.println("整体不匹配");
        }
    }
}

运行结果:

整体不匹配

2.2 Matcher

Matcher对象时对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共构造方法。

你需要调用Pattern对象的matcher方法来获得一个Matcher对象。

2.2.1 matcher.find()

matcher.find():尝试查找与该模式匹配的输入序列的下一个子序列

String content  = "hello111111 ok";
String regStr1 = "\\d+?";  

Pattern pattern = Pattern.compile(regStr1);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
     System.out.println("匹配到:"+matcher.group(0));
}

2.2.2 matcher.matches()

matcher.matches():整体匹配

 String content  = "hello111111 ok";
 String regStr1 = "\\d+?"; 

Pattern pattern = Pattern.compile(regStr1);
Matcher matcher = pattern.matcher(content);  
boolean flag = matcher.matches(); 	//整体匹配

2.2.3 matcher.replaceAll("")

matcher.replaceAll("") 字符串替换

 content = matcher.replaceAll("");

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:matcher.replaceAll的使用
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest12 {
    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);
       }
}

运行结果:

我我要学学学学编程Java!

2.3 PatternSyntaxExcepiton

PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式的语法错误。

3 基本语法

如果想灵活的运用正则表达式,必须了解其中各种元字符的功能,

元字符从功能上大致分为:

​ 1.限定符

​ 2.选择匹配符

​ 3.分组组合和反向引用符

​ 4.特殊字符

​ 5.字符匹配符

​ 6.定位符

​ 7.转义符号 \ \

3.1 转义符号

转义符号 \ \

说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,

​ 否则检索不到结果,甚至会报错的。

再次提示:在Java的正则表达式中,两个\ \代表其他语言中的一个\

​ Java中的转义是2个\

​ 需要用到转义符号的字符有以下: . * + ( ) $ / \ ? [ ] ^ { }

​ 比如:用 去 匹 配 “ a b c 去匹配“abc abc("会怎样?

​ 用(去匹配“abc$(”会怎样?

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:转义字符的验收
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest2 {
    public static void main(String[] args) {

        String content ="abc$(";

        String  reg = "\\(";
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("找到:"+matcher.group(0));
        }
    }
}

运行结果:

找到:(

3.2 字符匹配符

注意:[.]表示匹配就是.本身

语法:

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

应用实例:

1.[a-z]说明:

[a-z]表示可以匹配a-z中任意一个字符,比如[a-z]、[A-Z]去匹配a11c8会得到说明结果?

2.java正则表达式默认是区分字母大小写的,如何实现不区分大小写

​ 。(?i)abc 表示abc都不区分大小写

​ 。a(?i)bc 表示bc不区分大小写

​ 。a((?i)b)c 表示只有b不区分大小写

​ 。Pattern pat = Pattern.compile(regEx,Pattern.CASE_INSENSITIVE);

  1. [A-Z]表示可以匹配A-Z中任意一个字符。

​ [0-9]表示可以匹配0-9中任意一个字符。

4.[abcd]表示可以匹配abcd中任意一个字符。

5.[ ^abcd]表示可以匹配不是abcd中的任意一个字符。

​ 当然上面的abcd你可以根据实际情况修改,以适应你的需求

  1. \ \d 表示可以匹配0-9的任意一个数字,相当于[0-9]
  2. \ \D 表示可以匹配不是0-9中的任意一个数字,相当于[ ^0-9]
  3. \ \w 匹配任意英文字符、数字和下划线,相当于[a-zA-Z0-9_]
  4. \ \W 相当于[ ^a-zA-Z0-9_]
  5. \ \s 匹配任何空白字符(空格、制表符等)
  6. \ \S 匹配任何非空白字符,和 \ \s刚好相反
  7. .匹配初\n之外的所有字符,如果要匹配.本身则需要使用 \ \ .

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:演示字符匹配符的使用
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest3 {
    public static void main(String[] args) {

        String content  = "a11c8abcABC";

        //String regStr = "[a-z]";  //匹配a到z之间的任意一个字符
        //String regStr = "[A-Z]";  //匹配A到Z之间的任意一个字符
        String regStr = "abc"; //匹配abc 默认区分大小写
        Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE); //不区分大小写
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("匹配到:"+matcher.group(0));
        }
    }
}

3.3 选择匹配符 |

选择匹配符: 在匹配某个字符串的时候是选择性的,“或” 关系

​ 即:既可以匹配这个,又可以匹配那个,这时你需要用到选择匹配符 |

符号 符号含义 示例 示例含义
| 匹配“|”之前或之后的表达式 ab|cd ab或cd

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:选择匹配符
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest4 {
    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));
        }
    }
}

运行结果:

匹配到:han
匹配到:韩
匹配到:寒

3.4 限定符

限定符: 用于指定其前面的字符和组合项连续出现多少次 ? + * {3}

​ 注意:java匹配默认贪婪匹配:尽可能匹配多的

符号 符号含义 示例 示例含义 匹配输入
? 指定字符出现0次或1次(最多1次) m+abc? 以至少1个m开头,后接ab或abc的字符串 mab、mabc、mmmab、mmabc
+ 指定字符重复1次或n次(至少1次) m+(abc)* 以至少1个m开头,后接任意个abc的字符串 m、mabc、mabcabc
* 指定字符重复0次或n次(无要求) (abd)* 仅包含任意个abc的字符串,等效于\w* abc、abcabcabc
{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 com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:限定匹配符
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest5 {
    public static void main(String[] args) {

        String content  = "1111111aaahello";

        String regStr1 = "a{3}"; //表示匹配 aaa      匹配到:aaa
        String regStr2 = "1{4}"; //表示匹配 1111     匹配到:1111
        String regStr3 = "\\d{2}"; //表示匹配 两位的任意数字字符  匹配到:11 匹配到:11 匹配到:11

        Pattern pattern = Pattern.compile(regStr3);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("匹配到:"+matcher.group(0));
        }
    }
}

运行结果:

匹配到:11
匹配到:11
匹配到:11

3.5 定位符

定位符:规定要匹配的字符串出现的位置,

​ 比如在字符串的开始还是在结束的位置,这个也是相当有用的。

符号 符号含义 示例 示例含义 匹配输入
^ 指定起始字符 1+[a-z]* 以至少1个数字开头,后接任意个小写字母的字符串 123、6aa、555edf
$ 指定结束字符 2\ -[a-z]+$ 以1个数字开头后接连字符“_”,并以至少1个小写字母结尾的字符串 1-a
\ \b 匹配边界的字符串 han\ \b 这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置 hanshunpingsphan nnhan
\ \B 匹配非边界的字符串 han\ \B 和\ \b的含义刚刚相反 hanshunpingsphan nnhan

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:定位符的使用
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest6 {
    public static void main(String[] args) {

         String content  = "123_abc";
         //以至少1个数字开头,必须以至少1个小写字母结尾
        String regStr1 = "^[0-9]+\\_[a-z]+$";

        Pattern pattern = Pattern.compile(regStr1);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("匹配到:"+matcher.group(0));
        }
    }
}

运行结果:

匹配到:123_abc

例子:

1.汉字

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:汉子
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest9 {
    public static void main(String[] args) {

        //汉字
        String content  = "韩顺平教育";
        String regStr1 = "^[\u0391-\uffe5]+$";  

        Pattern pattern = Pattern.compile(regStr1);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()){
                    System.out.println("满足格式");
        }
    }
}

运行结果:

满足格式

2.邮政编码

要求:是1-9开头的一个六位数 比如:123890

 String content2  = "123890";
 String regStr2 = "^[1-9][0-9]{5}$";

3.QQ

要求:是1-9开头的一个5到10位数 数字

String content3  = "258921444";
String regStr3 = "^[1-9][0-9]{4,9}$";

4.手机号码

要求:必须以13,14,15,18开头的11位数,比如 13588889999

String content4  = "13588889999";
String regStr4 = "^1[3458][0-9]{9}$";

5.URL

String content5  = "https://www.bilibili.com/video/BV1fh411y7R8?from=search&seid=1831060912083761326";
String content6 = "https://live.bilibili.com/21395132?	·				   
                           hotRank=0&session_id=7c3539e60ecaf665700b4f7ae15374e2_02A1101E-A20D-43E4-BFE7-                             57D2F32ADA2A&launch_id=1000217&spm_id_from=333.851.b_62696c695f7265706f72745f6c697665.5";

String regStr5 = "^((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";

3.6 非贪婪匹配

符号 符号含义()
? 最小匹配,当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:非贪婪匹配
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest8 {
    public static void main(String[] args) {

        String content  = "hello111111 ok";
        String regStr1 = "\\d+?";  //非贪婪匹配

        Pattern pattern = Pattern.compile(regStr1);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("匹配到:"+matcher.group(0));
        }
    }
}

运行结果:

匹配到:1
匹配到:1
匹配到:1
匹配到:1
匹配到:1
匹配到:1

3.7 分组

分组:我们可以用()组成一个比较复杂的匹配模式,那么一个()的部分我们可以看作是一个分组/子表达式

符号 符号含义()
(正则表达式) 非命名捕获。捕获匹配的子字符串。编号为0的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号。
(?正则表达式) 命名捕获。将匹配的子字符串捕获到一个组名称或者编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如(?‘name’)

3.8 捕获

捕获:把正则表达式中分组匹配的内容,保存到内存中,以数字编号或者显式命名的组里,方便后面引用。

​ 从左向右,以分组的左括号为标志,

​ 第一个出现的分组的组号为1,

​ 第二个出现的分组的组号为2,以此类推。

​ 组0代表的是整个正则式

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:分组+捕获
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest7 {
    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 regStr1 = "(\\d\\d)(\\d\\d)";  //匹配2个数字的字符串

        Pattern pattern = Pattern.compile(regStr1);
        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));
        }
    }
}

运行结果:

匹配到:77891个分组:772个分组:89
    
匹配到:11891个分组:112个分组:89

3.9 反向引用

反向引用:()的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,

​ 这个我们成为反向引用,

​ 这种引用既可以是在正则表达式内部,内部反向引用 \ \分组号

​ 也可以是在正则表达式外部, 外部反向引用 $分组号

反向引用 很有用

例子:

1.要匹配两个连续的相同的数字

(\\d)\\1

2.要匹配五个连续的相同的数字

(\\d)\\1{4}

3.要匹配个位和千位相同,十位与百位相同的数字 比如:5225,1551

(\\d)(\\d)\\2\\1

4.请在字符串中检索商品编号,形式如:12321-333999111这样的号码,

要求满足前面是一个五位数,然后一个-号,然后是一个九位数,连续的每三位要相同

\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:反向引用
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest11 {
    public static void main(String[] args) {

        String content5  = "hello12321-333999111hanshunpinghello";
        String regStr5 = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";
        Pattern pattern = Pattern.compile(regStr5);
        Matcher matcher = pattern.matcher(content5);
        if (matcher.find()){
            System.out.println("找到"+matcher.group(0));
        }
    }
}

运行结果:

找到12321-333999111

5.经典的结巴程序

把类似:“我…我要…学学学学…编程Java!”,通过正则表达式修改成 “我要学编程Java”

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:经典的结巴程序
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest12 {
    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);

        //2.去掉重复的字     我要学学学学编程Java!
        //2.1 使用(.)\\1+
        //2.2 使用 反向引用$1 来替换 匹配的内容
         pattern = Pattern.compile("(.)\\1+");
         matcher =  pattern.matcher(content);
         content = matcher.replaceAll("$1");
         System.out.println(content);

         //3.使用一条语句 去掉重复的字
        String content1  = "我...我要...学学学学......编程Java!";
        content1 = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
        System.out.println(content1);
    }
}

运行结果:

我我要学学学学编程Java!
我要学编程Java!
我要学编程Java!

4 String类中使用正则表达式

4.1 替换功能

语法: str.replaceAll(regStr,“JDK”)

//将JDK1.3 JDK1.4统一改为JDK
String content = content.replaceAll("JDK1.3|JDK1.4", "JDK");

4.2 判断功能

语法:str.matches(regStr)

content = "13688889999";
boolean flag = content.matches("1(36|39)\\d{8}");

4.3 分隔功能

语法:str.split(reg);

 content = "hello#abc-jack12smith~北京";
String[] str = content.split("#|-|\\d+|~");

代码:

package com.tangguanlin.regexp;
import java.util.Arrays;
/**
 * 说明:String类使用正则表达式:替换+判断+分割
 * 作者:汤观林
 * 日期:2022年01月12日 00时
 */
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的计算能力有了大幅提升";

        //1.替换
        //使用正则表达式 将JDK1.3 JDK1.4替换为 JDK
        content = content.replaceAll("JDK1.3|JDK1.4", "JDK");
        System.out.println(content);

        //2.判断
        //要求:验证一个手机号,要求必须是136 139开头的11个数字
        content = "13688889999";
        boolean flag = content.matches("1(36|39)\\d{8}");
        if(flag){
            System.out.println("验证成功");
        }

        //3.分割
        //要求: 按照# 或者 - 或者 ~ 或者数字 来分隔
        content = "hello#abc-jack12smith~北京";
        String[] str = content.split("#|-|\\d+|~");
        System.out.println(Arrays.toString(str));
    }
}

运行结果:

20005月,JDK、JDK和J2SE1.3相继发布,几周后其获得了Apple公司Mac OS X的工业标准的支持。2001924日,J2EE1.3发布。2002226日,J2SE1.4发布。自此Java的计算能力有了大幅提升
    
验证成功
    
[hello, abc, jack, smith, 北京]

5 应用实例

5.1 验证电子邮件格式是否合法

规定电子邮件规则为:

​ (1)只能有一个@

​ (2)@前面是用户名,可以是a-zA-Z0-9 _ -字符

​ (3)@后面是域名,并且域名只能是英文字母,比如souhu.com

​ 写出对应的正则表达式,验证输入的字符串是否为满足规则

^[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+$

5.2 要求验证是不是整数或者小数

提示:这个要考虑正数和负数

比如:123, -345 ,34.8,-87.9,-0.01, 0.45等

^[+-]?([1-9]\\d*|0)(\\.\\d+)?$

5.3 对一个url进行解析

http://www.sohu.com:8080/abc/index.htm

(1)要求得到协议是什么 http

(2)域名是什么 www.sohu.com

(3)端口是什么 8080

(4)文件名是什么 index.htm

^([a-zA-Z]+)://([a-zA-Z.]+):(\d+)[\w-/]*/([\w.]+)$

代码:

package com.tangguanlin.regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 说明:解析url
 * 作者:汤观林
 * 日期:2022年01月11日 00时
 */
public class RegexpTest13 {
    public static void main(String[] args) {

        String content  = "http://www.sohu.com:8080/abc/index.htm";
         String regStr = "^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$";

         Pattern pattern = Pattern.compile(regStr);
         Matcher matcher =  pattern.matcher(content);
         if(matcher.matches()){
             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));
         }
    }
}

运行结果:

整体匹配:http://www.sohu.com:8080/abc/index.htm
协议:http
域名:www.sohu.com
端口:8080
文件:index.htm

6 常用Java正则表达式

常用的Java正则表达式:

校验数字的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

校验字符的表达式
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\”等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+

特殊需求表达式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份证号(15位、18位数字):^\d{15}|\d{18}$
短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
IP地址:((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}\2

钱的输入格式
有四种钱的表示形式我们可以接受:”10000.00″ 和 “10,000.00″, 和没有 “分” 的 “10000″ 和 “10,000″:^[1-9][0-9]*$
这表示任意一个不以0开头的数字,但是,这也意味着一个字符”0″不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
必须说明的是,小数点后面至少应该有1位数,所以”10.”是不通过的,但是 “10″ 和 “10.2″ 是通过的:^[0-9]+(.[0-9]{2})?$
这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
这样就允许用户只写一位小数。下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
备注:这就是最终结果了,别忘了”+”可以用”*”替代。如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里

  1. 0-9 ↩︎

  2. 0-9 ↩︎

你可能感兴趣的:(01Java,java)