Java --正则表达式学习

正则表达式学习

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

正则表达式:regular expression — RegExp

find() 和 group()

对matcher.find() 和 matcher.group() 部分过程的理解

package regexp;

import org.junit.jupiter.api.Test;

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

public class FindBottom {

    @Test
    public void Find_Bottom(){
        //匹配四个连着的数字 如1111,2346,....
        String regStr = "(\\d\\d)(\\d\\d)";
        String content = "1998年春天,我和我的父亲一起去北京,而2001年2月我和我的父亲去了上海";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            //   若正则表达式有分组()
            //   取出匹配的字符串规则如下:
            //   groups[0] 表示匹配到的子字符串
            //   groups[1] 表示匹配到的子字符串第 1 组子串
            //   groups[2] 表示匹配到的子字符串第 2 组子串
            //   以此类推... 但是不能越界
            System.out.println(matcher.group(0));
            System.out.println("第1组()匹配到的="+matcher.group(1));
            System.out.println("第2组()匹配到的="+matcher.group(2));
        }

        /*
         * matcher.find()完成的任务
         * 1.根据止跌那个的规则,定位满足规则的子字符串(如1998)
         * 2.找到后,将匹配到的字符串的开始位置的索引和结束位置的索引记录到 matcher对象的属性 int[] groups中
         *   以上面代码为例
         *      groups[0] = 0;  即 1998 的 1 的位置0
         *      groups[1] = 4;  即 1998 的 8 的位置3的下一个位置:3+1 = 4
         *
         * 3.同时记录matcher的属性oldLast = 匹配到的字符串的结束位置的索引+1,即4,用于下一次执行find()方法时的开始位置
         *
         *    while循环第二次matcher.find()时,会将原来的groups覆盖
         *      groups[0] = 21;  即 2001 的 2 的位置
         *      groups[1] = 25;  即 2001 的 1 的位置24的下一个位置:24+1 = 25
         *
         * 循环 matcher.find() 同理如上
         *
         * ---------------------------------------------------------------------------------------------------
         * 什么是分组?
         * 如(\\d\\d)(\\d\\d)做个正则表达式中有(),()表示分组,第1个()表示第1组,第2个()表示第2组
         * 以 1998 为例,匹配过程同上,但groups[]有变化
         *      groups[0] = 0、groups[1] = 4 这两个数值仍然为匹配到的子字符串的开始索引位置和结束索引位置
         *      groups[2] = 0、groups[3] = 2(1+1) 记录第 1 组() 匹配到的字符串
         *      groups[4] = 2、groups[5] = 4(3+1) 记录第 2 组() 匹配到的字符串
         *      若有更多分组以此类推...
         */

        /*
         *  matcher.group()完成的任务
         *  group()源码
         *  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();
         *  }
         *   根据groups[0] 和 groups[1] 的记录的位置,从content 开始截取子字符串并返回
         *      按本例1998来说 ,groups[0] = 0, groups[1] = 4 ,则返回 [0,4)content左闭右开区间内的子字符串:1998
         *            2001来说,groups[0] = 21, groups[1] = 25
         */
    }
}

1. 正则表达式语法

1. 转义符 \\

在 Java中\\ 表示其他语言中的\

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

package regexp;

import org.junit.jupiter.api.Test;

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

public class Regex01 {

    @Test
    public void test(){
        String content = "abc(def.gh";
        String regStr = "\\(";
        String regStr2 = "\\."; //匹配.字符
        String regStr3 = ".";   //匹配全部字符
        Pattern pattern = Pattern.compile(regStr2);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("匹配到"+matcher.group(0));
        }
    }
}

2. 字符匹配符

符号作用示例解释匹配输入
【】可接收的字符列表【efgh】e、f、g、h中的任意1个字符
【^】不接收的字符表【^abc】除a、b、c之外的任意一个字符,包括数字和特殊符号
-连字符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匹配单个非数字字符,相当于【^0-9】\\D{\\d}*以单个非数字字符开头,后接任意个数字字符串a、A342
\\w匹配单个数字、大小写字母字符、下划线,相当于【0-9a-zA-Z_】\\d{3}\\w{4}以3个数字字符开头的长度为7的数字字母字符串234abcd、12345Pe
\\W匹配单个非数字、大小写字母字符,相当于【^0-9a-zA-Z】\\W+\\d{2}以至少1个非数字字母字符开头,2个数字字符结尾的字符串#29、#?@10
\\s匹配任何空白字符(空格、制表符等)
\\S匹配任何非空白字符,和\\s相反

\\d\\d\\d == \\d{3}

+表示1个或多个

?表示0个或1个

*表示0个或多个

示例

package regexp;

import org.junit.jupiter.api.Test;

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

public class Regex01 {

    @Test
    public void test(){
        String content = "abcABCaBCAbcAbCabABcba";
        String regStr0 = "abc";
        String regStr1 ="(?i)abc";       //不区分 abc 大小写
        String regStr2 = "a(?i)bc";     //表示 bc 不区分大小写
        String regStr3 = "a((?i)b)c";   //表示 b 不区分大小写

        Pattern pattern1 = Pattern.compile(regStr0,Pattern.CASE_INSENSITIVE);   //不区分 abc 大小写
        Matcher matcher0 = pattern1.matcher(content);
        while (matcher0.find()) {
            System.out.println("匹配到"+matcher0.group(0));
        }
        /*
         * 匹配到abc
         * 匹配到ABC
         * 匹配到aBC
         * 匹配到Abc
         * 匹配到AbC
         * 匹配到ABc
         */
    }

    @Test
    public void test2() {
        String content = "abcAbc1234abc2a1";
        String regStr = "(?i)[^abc]";
        Pattern pattern = Pattern.compile(regStr);
        //两种效果相同
//        String regStr = "[^abc]";
//        Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);

        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }
        /*
         * 1
         * 2
         * 3
         * 4
         * 2
         * 1
         */
    }

    @Test
    public void test3(){
        String content = "a b   c"; //GBK 编码情况下,一个空格,一个制表符tab
        String regStr = "\\s";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()){
            System.out.println("找到"+matcher.group(0));
        }
        /* 说明在该编码格式下一个制表符等于3个空格
         * 找到
         * 找到
         * 找到
         * 找到
         */
    }
}

3. 选择匹配符 |

符号说明实例解释
|匹配“|”之前或之后的表达式ab|cdab或cd
@Test
public void test4(){
    String content = "你好世界,hello world";
    String regStr = "你|hello|ld";
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()){
        System.out.println(matcher.group(0));
    }
    /*
     * 你
     * hello
     * ld
     */
}

4. 限定符

跟在谁后面谁就要受到约束,若是一个整体则要跟到一个括号后面

符号含义示例说明匹配输入
*指定字符重复0次或n次(abc)*仅包含任意个abc的字符abc、abcabcabc
+指定字符重复1次或n次(至少1次)m+(abc)*以至少1个m开头,后接任意个abc的字符串m、mabc、mabcabc
指定字符重复0次或1次(最多1次)m+abc?以至少1个m开头,后接ab或abc的字符串mab、mabc、mmmab、mmmmabc
{n}指定只能出现n个匹配字符【abcd】{3}由abcd中字母组成的任意长度为3的字符串abc、dbc、adc
{n,}指定至少n个匹配字符【abcd】{3,}由abcd中的字母组成的任意长度不小于3的字符串aab、bdc、aaabdc
{n,m}指定至少n个但不多于m个匹配字符【abcd】{3,5}由abcd中字母组成的任意长度不小于3,不大于5的字符串abc、abcd、aaaa、bcdab
@Test
public void test5() {
    String content = "mmabcabcamabcabcabcm";
    String regStr = "m+(abc)*";
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()){
        System.out.println(matcher.group(0));
    }
    /*
     * mmabcabc
     * mabcabcabc
     * m
     */

    String content2 = "aaaaab";
    String regStr2 = "a{3,5}";  //a出现至少3次,至多5次
    Pattern pattern2 = Pattern.compile(regStr2);
    Matcher matcher2 = pattern2.matcher(content2);
    while (matcher2.find()){
        System.out.println(matcher2.group(0));
    }
    /* java正则匹配时贪婪匹配,尽可能匹配多的
     * aaaaa
     */

    String content3 = "a11aaa1ab";
    String regStr3 = "a1+";  //a开头,1至少重复1次
    Pattern pattern3 = Pattern.compile(regStr3);
    Matcher matcher3 = pattern3.matcher(content3);
    while (matcher3.find()){
        System.out.println(matcher3.group(0));
    }
    /*
     * a11
     * a1
     */


    String content4 = "a11aaa1ab";
    String regStr4 = "a1*";  //a开头,1出现0-n次
    Pattern pattern4 = Pattern.compile(regStr4);
    Matcher matcher4 = pattern3.matcher(content4);
    while (matcher4.find()){
        System.out.println(matcher4.group(0));
    }
    /* 这里也体现了贪婪匹配,1可以出现0次的,但是这里优先匹配多个1
     * a11
     * a1
     */
}

5. 定位符

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

import org.junit.jupiter.api.Test;

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

public class Regex02 {

    @Test
    public void test01(){
        String content = "123abc";
        String regStr ="^[0-9]+[a-z]*";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("找到 ->"+matcher.group(0));
        }
        /*
         *  找到 ->123abc
         */
        //注意:若content = “ a123abc ” 则什么都没有匹配成功
    }

    @Test
    public void test02(){
        String content = "hannn nnhan xhanx";
        String regStr = "han\\b";   //边界既可以是有空格处的,也可以是字符串的末尾处
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }
        /*
         * han
         */
        System.out.println("--------------");

        String regStr2 = "han\\B";
        pattern = Pattern.compile(regStr2);
        matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }
        /*
         * han
         * han
         */
    }

}

6. 分组

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

特别分组

常用分组构造形式说明
(?:pattern)匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储以后使用的匹配,这对于”or“字符(|)组合模式部件的情况很有用。例如 ‘indutr(?|ies)’ 是比 ‘industry|industries’ 更经济的表达式
(?=pattern)它是一个非捕获匹配。例如 ‘Windows(?=95|98|NT|2000)’ 匹配"Windows2000"中的"Windows",但不匹配 “Windows3.1"中的"Windows”
(?!pattern)该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配。例如 “Windows(?!95|98|NT|2000)” 匹配 “Windows3.1"中的 “Windows”,但不匹配"Windows2000"中的"Windows”
package regexp;

import org.junit.jupiter.api.Test;

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

public class Regex03 {
    @Test
    public void test(){
        String content = "hello world 2022年5月12345678";
        String regStr = "(?<arr1>\\d\\d)(?<arr2>\\d\\d)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("匹配到的字符串:"+matcher.group(0));
            System.out.println("第一组的子字符串:"+matcher.group("arr1"));
            System.out.println("第二组的子字符串:"+matcher.group("arr2"));
            System.out.println();
        }
        /*
         * 匹配到的字符串:2022
         * 第一组的子字符串:20
         * 第二组的子字符串:22
         *
         * 匹配到的字符串:1234
         * 第一组的子字符串:12
         * 第二组的子字符串:34
         *
         * 匹配到的字符串:5678
         * 第一组的子字符串:56
         * 第二组的子字符串:78
         */
    }
}
 @Test
    public void test2(){
        String content = "小明 老师hhh小明同学xxx小明教育hello,今日头条,热搜榜第一是...";
        String regStr = "小明(?:老师|同学|教育)";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));      //true
//            System.out.println(matcher.group(1));   //error,由于是不捕获的,所以无法使用索引去获取
        }
        /*
         * 小明老师
         * 小明同学
         * 小明教育
         */
    }

更多元字符可以去网上查询

7. 非贪婪匹配

@Test
public void test3(){
    String content = "hello111111";
    String regStr = "\\d+";     //默认贪婪匹配
    String regStr2 = "\\d+?";   //设置成非贪婪匹配
    /*
     *  设置非贪婪匹配,即在限定符后 加 ?
     */
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()) {
        System.out.println(matcher.group(0));
    }
    /*
     * 111111
     */


    Pattern pattern1 = Pattern.compile(regStr2);
    Matcher matcher1 = pattern1.matcher(content);
    while (matcher1.find()){
        System.out.println(matcher1.group(0));
    }
    /*
     * 1
     * 1
     * 1
     * 1
     * 1
     * 1
     */
}

8. 练习

package regexp;

import org.junit.jupiter.api.Test;

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

public class Works {

    @Test
    public void Check_Chinese_charactersChild() {
        String content = "你好世界";
        String regStr = "^[\u4e00-\u9fa5]+$";    //这是汉字的编码范围
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        if(matcher.find()){
            System.out.println("满足格式");
        }else {
            System.out.println("不满足格式");
        }
    }

    @Test
    public void Check_phoneNumber(){
        /*
            匹配 11位电话号码,要求开头必须是13 14 15 18 其中之一
         */
        String content = "13911111111";
        String regStr = "^1[3458]\\d{9}";   //"^1[3|4|5|8]\\d{9}"这样写是错的,【】里面写 | 就会把 | 也当作一个符号而不是 或 的意思
//        regStr = "^1(?:3|4|5|8)\\d{9}"; //这样是对的
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("满足格式");
        }else {
            System.out.println("不满足格式");
        }
    }

    @Test
    public void Check_url(){
        String content = "https://leetcode-cn.com/problems/minimum-genetic-mutation/";

        String regStr = "^(https?://)?([\\w-]+\\.)+[\\w-]+(/[\\w-?%=#&/.]*)?$";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("满足格式");
        }else {
            System.out.println("不满足格式");
        }
    }

    @Test
    public void tests(){
        String content = "a b c";
        String regStr ="."; //匹配除了\n的所有字符
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }
    }
}

2. 正则表达式三个常用类

1. Pattern类

pattern对象是一个正则表达式对象。Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数,如 Pattern p = Pattern.compile(regStr)

2. Matcher类

Matcher对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共的构造方法。你需要调用Pattern对象的matcher方法 来获取一个Matcher对象

方法及说明
public int start() 返回以前匹配的初始索引
public int start(int group) 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
public int end() 返回最后匹配字符之后的偏移量
public Int end(int group) 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量
public boolean lookingAt() 尝试将从区域开头开始的输入序列与该模式匹配
public boolean find() 尝试查找与该模式匹配的输入序列的下一个子序列
public boolean find(int start) 重置此匹配器,然后尝试查找匹配该模式,从指定索引开始的输入序列的下一个子序列
public boolean matches() 尝试将整个区域与模式匹配
package regexp;

import org.junit.jupiter.api.Test;

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

public class Regex05 {

    @Test
    public void test1(){
        String content = "hello world,hello Java,hello C";
        String regStr = "hello";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("索引开始位置:"+matcher.start());
            System.out.println("索引结束位置:"+matcher.end());
            System.out.println(content.substring(matcher.start(), matcher.end()));
            System.out.println("===================");
        }
        /*
         * 索引开始位置:0
         * 索引结束位置:5
         * hello
         * ===================
         * 索引开始位置:12
         * 索引结束位置:17
         * hello
         * ===================
         * 索引开始位置:23
         * 索引结束位置:28
         * hello
         * ===================
         */


        //整体匹配matches() 方法常用于校验某个字符串是否满足某个规划
        System.out.println("整体匹配-->"+matcher.matches());    //false
        System.out.println("========================");

        //完成如果content含有Java,则替换成Golang
        regStr = "Java";
        pattern = Pattern.compile(regStr);
        matcher = pattern.matcher(content);
        //注意:replaceAll 返回的字符串才是替换后的字符串,原来的字符串不会变化
        String newContent = matcher.replaceAll("Golang");
        System.out.println("替换后的content:"+newContent);
        System.out.println("替换前的content:"+content);
        /*
         * 替换后的content:hello world,hello Golang,hello C
         * 替换前的content:hello world,hello Java,hello C
         */

        pattern = Pattern.compile("\\d+");
        matcher = pattern.matcher("123abc");
        boolean b = matcher.lookingAt();
        System.out.println(b);  //true,因为lookingAt是对要匹配的字符串前面部分进行匹配,如果前面部分有 规定的模式,则返回true否则返回false

        matcher = pattern.matcher("abc123");
        boolean b1 = matcher.lookingAt();
        System.out.println(b1); //false
    }
}

Pattern.matches()方法

package regexp;

import org.junit.jupiter.api.Test;

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

public class Regex04 {

    /**
     * 使用 Pattern.matches(regex,input)方法 -- 整体匹配 ,能减少一些代码
     */
    @Test
    public void test1(){
        String content = "hello world,I am coming!";
        String regStr = "hello";
        boolean matches = Pattern.matches(regStr, content);
        //这里matches(regStr,content)等同于
//         Pattern pattern = Pattern.compile("^(hello)$");
//         Matcher matcher = pattern.matcher(content);
//        boolean matches = matcher.matches();
        
        System.out.println("整体匹配-->"+matches);  //整体匹配-->false

        regStr = "hello.*";
        boolean matches1 = Pattern.matches(regStr, content);
        System.out.println("整体匹配-->"+matches1);     //整匹配-->true
    }
}

3. PatternSyntaxException

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


3. 反向引用

image-20220508092617709

@Test
public void Back_reference(){
    String content = "1221 1234 2442 1111 8919 1882 1891";
    // 分组() ,分组以括号括起来,组号从1开始
    // 以分组 捕获的形式,反向引用第一组 \\1 反向引用第二组 \\2
    /*
     匹配 4 位 回文数:千位和个位相同,百位和十位相同
     */
    String regStr = "(\\d)(\\d)\\2\\1";
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()) {
        System.out.println("匹配到 "+matcher.group(0));
    }
    /*
     * 匹配到 1221
     * 匹配到 2442
     * 匹配到 1111
     */

    /*
        匹配 前5位为回文数,后9位分别3位一组,每组都相等
     */
    content = "12321-333999111 11111-111222333 12345-222333444 1331-221133 1221-11122111 4554-22221133";
    String regStr2 = "(\\d)(\\d)\\d\\2\\1-(\\d)\\3{2}(\\d)\\4{2}(\\d)\\5{2}";
    Pattern pattern2 = Pattern.compile(regStr2);
    Matcher matcher2 = pattern2.matcher(content);
    while (matcher2.find()) {
        System.out.println("匹配到 "+matcher2.group(0));
    }
}

结巴 程序

/**
 * 结巴程序,将结巴语句 恢复成正常语句
 * 自己写的
 */
@Test
public void Stutter_procedure(){
    String content = "我我我要要要学学编程程";
    StringBuilder newContent = new StringBuilder();
    String regStr = "([\u4e00-\u9fa5])\\1*";
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    while (matcher.find()) {
        newContent.append(matcher.group(1));
    }
    System.out.println(newContent);
}

/*
 * 学习的写法
 */
@Test
public void Stutter_procedure2(){
    String content = "我...我我要..要要学学...编程....程";
    String regStr = "\\.";
    Pattern pattern = Pattern.compile(regStr);
    Matcher matcher = pattern.matcher(content);
    content = matcher.replaceAll("");

    regStr = "(.)\\1+";
    pattern = Pattern.compile(regStr);
    matcher = pattern.matcher(content);
    //外部(非正则表达式regStr)使用分组时,要用 $
    content = matcher.replaceAll("$1");
    System.out.println(content);
}

/**
 * 简单写法
 */
@Test
public void Stutter_procedure3(){
    String content = "我...我我要..要要学学...编程....程";
    content = Pattern.compile("\\.").matcher(content).replaceAll("");

    content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
    System.out.println(content);
}

4. String类中使用正则表达式

方便之处:不用再构造一个Pattern和Matcher了

替换功能:

String 类的 public String replaceAll(String regex,String replacement)
@Test
public void StringReplace1(){
    String content = "1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一种独立的开发工具。9月,约8.3万个网页应用了Java技术来制作。10月,Sun公司发布了Java平台的第一个即时(JIT)编译器。\n" +
            "1997年2月,JDK 1.1面世,在随后的3周时间里,达到了22万次的下载量。4月2日,Java One会议召开,参会者逾一万人,创当时全球同类会议规模之纪录。9月,Java Developer Connection社区成员超过10万。\n" +
            "1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。";
    //使用正则表达式 将Java 和 J2EE 替换成 JavaavaJ
    content = content.replaceAll("Java|J2EE","JavaavaJ");
    System.out.println("替换后:"+content);
}

判断功能:

String 类的 public boolean matches(String regex)
/*
要求验证一个手机号11位,必须以138 或 139 开头
 */
@Test
public void Check_phoneNumber(){
    String content = "13888888888";
    if(content.matches("1(?:38|39)\\d{8}")){
        System.out.println("验证成功");
    }else {
        System.out.println("验证失败");
    }
}

分割功能:

String 类的 public String[] split(String regex)
@Test
public void Splits(){
    String content = "hello#abc-tom99jerry~北京";
    String[] split = content.split("-|#|~|\\d+");//用 - # ~ \d+ 进行分割字符串
    for(String it:split){
        System.out.println(it);
    }
    /*
     * hello
     * abc
     * tom
     * jerry
     * 北京
     */
}

  1. 0-9 ↩︎

  2. 0-9 ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值