韩顺平Java学习笔记_正则表达式专题(非常实用!)

目录

一 快速入门 

​编辑

二 正则表达式基本语法

三 三个常用类

四 分组, 捕获, 反向引用

五 String类中使用正则表达式

 

一 快速入门 

重点看底层原理!

1.优点(可略过,主要是体验正则表达式的便捷)

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第1张图片

        //假定,编写爬虫,从百度页面得到文本
        String content = "根据PC-Meter1996年的调查,平均每个互联网用户每次访问的环球网的网站有5.6个," +
                "每次查看的网页20.8个,而平均阅读每一个网页所需要的时间大约1.4分钟,平均每次上网阅读环球网页的时间大约28分钟。" +
                "作为这样一种具有私人和公共的双重功用的传媒,互联网效用的实现从根本上还是依赖于参与者," +
                "也就是用户的增加。而这一特性又是和网络的性质是完全一致的。";
        //提取所有英文单词|所有数字|字母和数字
        //1.县创建一个Pattern对象
//        Pattern pattern = Pattern.compile("[a-zA-Z]");
//        Pattern pattern = Pattern.compile("[0-9]+");
        Pattern pattern = Pattern.compile("[a-zA-Z]|[0-9]+");
        //2.创建一个匹配器对象
        Matcher matcher = pattern.matcher(content);
        //3.循环匹配
        while(matcher.find()){
            System.out.println(matcher.group(0));
        }

2.基本介绍 

 3.底层原理

package com.hspedu.regexp;
import java.util.regex.Matcher; import java.util.regex.Pattern;
/**
* @author 韩顺平 * @version 1.0
* 分析 java 的正则表达式的底层实现(重要.)
*/
public class RegTheory {
public static void main(String[] args) {
String content = "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 平台的企业版),应" + "用 3443 于基于 Java 的应用服务器。Java 2 平台的发布,是 Java 发展过程中最重要的一个" + "里程碑,标志着 Java 的应用开始普及 9889 ";
//目标:匹配所有四个数字
//说明
//1. \\d 表示一个任意的数字
String regStr = "(\\d\\d)(\\d\\d)";
//2. 创建模式对象[即正则表达式对象] Pattern pattern = Pattern.compile(regStr); //3. 创建匹配器
//说明:创建匹配器 matcher, 按照 正则表达式的规则 去匹配 content 字符串 Matcher matcher = pattern.matcher(content);
//4.开始匹配 /**
*
* matcher.find() 完成的任务 (考虑分组)
什么是分组,比如 (\d\d)(\d\d) ,正则表达式中有() 表示分组,第 1 个()表示第 1 组,第 2 个()表示第 2 组... 1. 根据指定的规则 ,定位满足规则的子字符串(比如(19)(98))
2. 找到后,将 子字符串的开始的索引记录到 matcher 对象的属性 int[] groups;
2.1 groups[0] = 0 , 把该子字符串的结束的索引+1 的值记录到 groups[1] = 4 2.2 记录 1 组()匹配到的字符串 groups[2] = 0 groups[3] = 2
2.3 记录 2 组()匹配到的字符串 groups[4] = 2 groups[5] = 4 2.4.如果有更多的分组.....
3. 同时记录 oldLast 的值为 子字符串的结束的 索引+1 的值即 35, 即下次执行 find 时,就从 35 开始匹配
matcher.group(0) 分析
   * * * *
源码:
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();
1. 根据 groups[0]=31 和 groups[1]=35 的记录的位置,从 content 开始截取子字符串返回
就是 [31,35) 包含 31 但是不包含索引为 35 的位置 如果再次指向 find 方法.仍然安上面分析来执行
 
*/
while (matcher.find()) {
//小结
//1. 如果正则表达式有() 即分组
//2. 取出匹配的字符串规则如下
//3. group(0) 表示匹配到的子字符串
//4. group(1) 表示匹配到的子字符串的第一组字串
//5. group(2) 表示匹配到的子字符串的第 2 组字串
//6. ... 但是分组的数不能越界.

System.out.println("找到: " + matcher.group(0)); 
System.out.println("第 1 组()匹配到的值=" + matcher.group(1)); System.out.println("第 2 组()匹配到的值=" + matcher.group(2));
} }
}

二 正则表达式基本语法

1.元字符 -转义符:在检索某些特殊字符的时候,要用到转移符号,否则会报错

Note:在Java的正则表达式中,用两个\\表示其他语言中的一个\

例子:

/**
 * 演示转义符
 */
public class RegExp02 {
    public static void main(String[] args) {
        String content = "abc$(abc(123(";
        //匹配(
        String regStr = "\\(";//要用\\转义,否则报错
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            System.out.println(matcher.group(0));
        }
    }
}
需要用到转移符号的字符如下: . * + ( ) $ / \ ? [ ] ^ { }

2.元字符 -字符匹配符

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第2张图片

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第3张图片

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第4张图片

 3.元字符 -选择匹配符: 匹配某个字符串时是选择性的,比如既可以匹配这个,又可以匹配那个,则需要用到选择匹配符

|  表示或者

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

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第5张图片

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第6张图片

5.定位符:规定要匹配的字符串出现的位置,比如再开始还是结束位置,非常有用! 

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第7张图片

6.分组 

(pattern) 非命名捕获.

捕获匹配的子字符串,编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号顺序由1开始自动编号.

(?pattern) 命名捕获.

将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符号,并且不能以数字开头.可以使用单引号替代尖括号,例如(?'name').

特别分组

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第8张图片

练习:

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第9张图片

7.非贪婪匹配

正则匹配默认是贪婪匹配,如果在限定符后加?即变成非贪婪匹配,这时会尽可能匹配少的

8.应用实例 

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第10张图片

 

三 三个常用类

Pattern:正则表达式

Matcher:对输入字符串进行解释和匹配的引擎

PatternSyntaxException:表示一个正则表达式模式中的语法错误

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第11张图片

 1. Pattern类的方法matches --> 整体匹配,返回boolean

public class PatternMethod {
    public static void main(String[] args) {
        String content = "hello abc hello, 韩顺平教育";
        String regExp = "hello.*";
        boolean matches = Pattern.matches(regExp, content);
        System.out.println("整体匹配=" + matches);
    }
}

2. Matcher类

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第12张图片

常用方法的演示: 

public class MatcherMethod {
    public static void main(String[] args) {
        String content = "hello hspedu jack tom hello smith hello";
        String regExp = "hello";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println("--------");
            System.out.println(matcher.start());
            System.out.println(matcher.end());
            System.out.println(content.substring(matcher.start(), matcher.end()));
        }
        //整体匹配,常用于校验某个字符串是否满足某个规则
        System.out.println("整体匹配: " + matcher.matches());

        //完成如果conteng 有hspedu 就替换成韩顺平教育
        String regStr = "hspedu";
        Pattern pattern1 = Pattern.compile(regStr);
        Matcher matcher1 = pattern1.matcher(content);
        String newStr = matcher1.replaceAll("韩顺平教育");//返回的字符串才是替换后的,原来的content不变化
        System.out.println("new: " + newStr);
        System.out.println("old: " + content);

    }
}

四 分组, 捕获, 反向引用

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第13张图片

韩顺平Java学习笔记_正则表达式专题(非常实用!)_第14张图片

 案例练习一:

public class 反向引用 {
    public static void main(String[] args) {
        String content = "hello jack 12321-333999111 tom11111 jack22 yyy xxx";//找到12321-333999111
        String regStr = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";
        Pattern pattern = Pattern.compile(regStr);
        Matcher matcher = pattern.matcher(content);
        while(matcher.find()){
            System.out.println("找到 " + matcher.group(0));
        }
    }
}

案例练习二(结巴去重):

//案例2:结巴去重
        String content = "我...我要....学学学学....编程Java!";
        //1.去掉所有的.
        Pattern pattern = Pattern.compile("\\.");
        Matcher matcher = pattern.matcher(content);
        content = matcher.replaceAll("");
        System.out.println("content = " + content);
        //我我要学学学学编程Java!
        //2.去掉重复的字
        //思路
        //(1)使用(.)\\1+
        //(2)使用反向引用$1来替换得到的内容
//        Pattern pattern1 = Pattern.compile("(.)\\1+");//分组会被记录到$1
//        Matcher matcher1 = pattern1.matcher(content);
//        while (matcher1.find()) {
//            System.out.println("找到" + matcher1.group(0));
//        }
//        //使用反向引用$1来替换得到的内容
//        content = matcher1.replaceAll("$1");
//        System.out.println(content);
        //3,使用一条语句去重
        content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
        System.out.println(content);

五 String类中使用正则表达式

1.替换

String类 public String replaceAll(String regex,String replacement)

2.判断

String类 public boolean matches(String regex)

3.分割

String类 public String[] split(String regex)

你可能感兴趣的:(学习)