正则表达式(RegExp---regular expression)

正则表达式是字符串执行模式匹配的技术

流程

  1. 写出正则表达式
   String regStr = "\\d\\d\\d\\d";//这里\\d表示任意一个数字,四个代表四个数字

  1. 创建模式对象,即正则表达式对象
    Pattern pattern = Pattern.compile(regStr);
    
  2. 创建匹配器
    Matcher matcher = pattern.matcher(content);//content就是要查询的原文
    
  3. 开始匹配
    /**
    *matcher.find 完成的任务
    *1. 根据规则,定位满足规则的子字符串(如1998)
    *2. 找到后,将子字符串的开始索引记录到matcher对象的属性int[] groups, groups[0]为字符串开始位置的索引值,groups[1]为结束的索引+1的值,即下次执行find开始的位置 
    */
    while(matcher.find())
    {
        System.out.println("找到:"+ matcher.group(0));
    }
    

groups()

  1. 什么是分组: 表达式中有()就表示分组,一个括号为一组,比如"(\d\d)(\d\d)"就分成了两组
  2. 在matcher找到后,子字符串的开始的索引记录将记录到matcher对象的属性int[] groups中,假如找到了数字1998
    1. groups[0] 记录的是开始的索引(1的位置)
    2. groups[1] 记录的是结束的位置索引+1(8后面一个位置)
    3. groups[2] 记录的是(19)(98)中第一组的1的位置
    4. groups[3] 记录的是(19)(98)中第一组的9的位置+1
    5. groups[4] 记录的是(19)(98)中第二组的9的位置
    6. groups[5] 记录的是(19)(98)中第二组的8的位置+1
    7. 如果有更多分组就以此类推...
  3. matcher.group(int group)则是
    1. matcher.group(0)得到匹配到的字符串
    2. matcher.group(1)得到匹配到的字符串的第一个分组内容
    3. matcher.group(2)得到匹配到的字符串的第二个分组内容
    4. ... 注意不要越界
  4. 如果是命名分组,即比如比如"(?<g1>\d\d)(?<g2>\d\d)"就是可以用 matcher.group("g1") 和matcher.group("g2)来获得第一和第二分组的结果

语法

元字符从功能上分为:

  1. 限定符
  2. 选择匹配符
  3. 分组组合和反向引用符
  4. 特殊字符
  5. 字符匹配符
  6. 定位符

转义号\---检索特殊字符需要用

java的正则表达式中,两个\代表其他语言中的一个\

需要用到转义符号的字符有: . * + ( ) <span data-formula=" / \ ? [ ] ^ { }

字符匹配符

符号 功能 示例 解释
[] 可接受的字符列表 [efgh] e、f、g、h中的任意一个字符
[^] 不可接受的字符列表 [^abc] 除a、b、c之外的任意一个字符,包括数字和特殊符号
- 连字符 A-Z 任意单个大写字母

alt text 里面的?代表0个或1个,+代表至少1个,*代表任意多个, {n}代表连续n个

应用实例:

  1. [a-z] 匹配a-z任意一个字符
  2. java正则表达式默认区分字母大小写,如何不区分呢
    1. (?i)abc表示abc都不区分大小写
    2. a(?i)bc表示bc不区分大小写
    3. a((?i)b)c表示只有b不区分大小写
    4. Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
  3. [^a-z]匹配不是a-z的任意一个字符
  4. [abcd]表示可以匹配abcd中任意一个字符
  5. [^abcd]
  6. \d匹配0-9任意一个数字=[0-9]
  7. \D匹配不是0-9中的任意一个数字=[^0-9]
  8. \w匹配任意英文字符、数字和下划线=[a-zA-Z0-9]
  9. \W为\w取反
  10. \s匹配任何空白字符(空格、制表符等)
  11. \S上面取反
  12. . 匹配除\n之外的所有字符,如果要匹配.本身,要使用\.或者[.],[]里面的特殊字符就是本身的含义

选择匹配符

想要既匹配这个,又匹配那个,就要用到选择匹配符 alt text ab|cd 匹配ab或者cd

限定符

alt text alt text

1111111aaaaheloo 使用a{3,4}去匹配表示匹配aaa或者aaaa,这里java的匹配是贪婪匹配,尽量匹配多的,所以这里只会返回一个aaaa。

而使用\d{2,5}会返回一个11111和一个11

定位符

定位符,规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的。 alt text

分组

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

非贪婪匹配

\d+ 默认为贪婪匹配 \d+?就是非贪婪匹配

Pattern类

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

Pattern.matches(regStr, content)是整体匹配,返回boolean值,不返回匹配的内容

Matcher类

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

PatternSyntaxException

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

分组、捕获、反向引用

  1. 分组 用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看做是一个子表达式/一个分组。
  2. 捕获 把正则表达式中表达式/分组匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个2,以此类推。组0代表的是整个正则式
  3. 反向引用 圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\\分组号,外部反向引用" aria-hidden="true">分组号
    1. 比如要匹配两个连续的相同数字: (\d)\1
    2. 匹配五个连续的相同数字:(\d)\1{4}
    3. 要匹配个位与千位相同,十位与百位相同的数 5225,1551: (\d)(\d)\2\1

String类中使用正则表达式

  1. 替换 public String replaceAll(String regex, String replacement)
  2. 判断 public boolean matches(String regex){ }
  3. 分割 public String[] split(String regex)

本文章使用limfx的vscode插件快速发布