<Java>25 正则表达式

本文最后更新于:2022年6月19日 晚上

25 正则表达式

正则表达式:对字符串执行模式匹配的技术。一个正则表达式,就是用某种模式去匹配字符串的一个公式。除 Java 外,还有许多语言支持正则表达式。

String content = "HeruinKCoin";				//对象文本
String regular = "[A-Z]";					//[1] 创建规则
Pattern pattern = Pattern.compile(regular);	//[2] 创建模式对象
Matcher matcher = pattern.matcher(content);	//[3] 创建匹配器
while (matcher.find()){						//[4] find() 是否找到下一个
    System.out.println(matcher.group(0));	//[5] group(0) 输出找到的当前对象
}

Matcher 底层维护了一个 group[] 数组。如果 [4] 在文本里匹配到对象,会在 group[0] 记载该起始位置 n1,在 group[1] 记录该结束位置的下一位 n2。即 [n1,n2) 为匹配的字符串,n2 位置是下次匹配的起始位置。

[1] 创建的规则包含分组(如 String regular = "(\\d\\d)(\\d\\d)";),则第一组的起止位置记录在 group[2]group[3],第二组在 group[4]group[5]。以此类推。这时,[5]group(0) 代表输出全部,group[1] 代表输出第一组,以此类推。

25.1 语法

元字符

  • 限定符
  • 选择匹配符
  • 分组组合和反向引用符
  • 特殊字符
  • 字符匹配符
  • 定位符

25.1.1 转义符号 \

使用正则表达式去检索某些特殊字符时,需要加上转义符号(如:( 需要写成 \(

在 Java 的正则表达式中,\\ 代表一个 \——见 [1.8 Java 转义字符 ]

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

25.1.2 字符匹配符

符号 含义 示例 解释
[ ] 可接收的字符列表 [abcd] abcd 中的任一字符
[^] 不接收的字符列表 [^abcd] 非 abcd 的任意字符
- 连字符 [a-z] a - z 中的任意字符
. 匹配除 \n 外的任意字符 a..b a 开头,b结尾,中间含 2 字符
\d 匹配单个数字字符 \d{3} 包含 3 个数字
\D 匹配单个非数字字符 \D(\d)* 单个非数字字符开头,后接任意个数字字符
\w 匹配单个数字、大小写字母字符 \w{2}\d{3} 2 个数字字母字符开头,后接 3 个数字字符
\W 匹配单个非数字、非大小写字母字符 \W+\d{2} 以至少 1 个非数字字母字符开头,后接 2 个数字字符
\s 匹配空白字符(空格、制表位等)
\S 匹配非空白字符
  • 关于 .:特别地,出现 [.] 的场合,那个小圆点依然表示小圆点。[?] 同理,表示问号

  • 正则表达式默认区分大小写。要不区分大小写,就加上 (?i)

    • (?i)abc:即 abc 都不区分大小写

    • a(?i)bc:即仅 bc 不区分大小写

    • a((?i)b)c:即仅 b 不区分大小写

    • 创建模式对象时,若如此做:

      Pattern pattern = Pattern.compile(regular, Pattern.CASE_INSENSITIVE);

      这个场合,也能不区分大小写。

25.1.3 选择匹配符 |

……我的感想是,和 Java 的逻辑或 | 一样!

25.1.4 限定符

符号 含义 示例 解释
* 指定字符重复任意次(可以为 0 次) (abc)* 仅包含任意个 abc 字符串的字符串
+ 指定字符重复至少一次 m+(abc)* 以任意个 m 开头,后面可以有 abc 字符串的字符串
? 指定字符重复最多一次(可以为 0 次) m+abc? 以任意个 m 开头,后面可以有最多一个 abc 字符串的字符串
{n} n 个匹配 [abc]{3} 长度为 3 的 abc 中的任意字符的组合
{n,} 至少 n 个匹配 [abc]{3,} 长度不小于 3 的 abc 中的任意字符的组合
{n,m} n 到 m 个匹配 [abc]{3,5} 长度介于 3 到 5 之间的 abc 中的任意字符的组合
  • Java 的匹配模式默认是贪婪匹配。即:aaaaa 匹配 a{3,5} 的场合,会匹配到 aaaaa

    希望实现非贪婪匹配,可以添加额外的 ?。如:*?+??? 代表各自规则的非贪婪匹配

25.1.5 定位符

符号 含义 示例 解释
^ 指定起始字符 ^[0-9]+[a-z]* 至少一个数字开头,后接任意小写字母字符串
& 指定结束字符 ^[0-9][a]$ 一个数字开头,一个 a 结尾
\b 匹配目标字符串的边界 K\.C\b 匹配边界的 K.C
\B 匹配目标字符串的非边界 K\.C\B 匹配非边界的 K.C
  • 边界即字符串的末尾,或字符串中空格间隔的子串的末尾。

25.1.6 分组

符号 含义
(pattern) 非命名捕获。捕获匹配的字符串。
(?<name>pattern)(?'name'pattern) 命名捕获。用于 name 的字符串不能包含标点符号,也不能以数字开头
  • 编号为 0 的第一个捕获是由整个正则表达式匹配的文本。其他捕获结果根据左括号的顺序从 1 开始自动编号。

25.1.7 非捕获分组

符号 含义 示例 解释
(?:pattern) 匹配 pattern 但不捕获该匹配的子表达式。 `industr(?:y ies)`
(?=pattern) 匹配处于 pattern 前的搜索字符串。非捕获分组。 `Windows(?=7 10
(?!pattern) 匹配不处于 pattern 前的搜索字符串。非捕获分组。 `Windows(?!7 10

25.2 常用类

  • Pattern 类:

    Pattern 对象是一个正则表达式对象,该类没有公共构造方法。

    Pattern.compile(reg) 获取一个 Pattern 对象。

  • Matcher 类:

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

    Pattern 对象的 matcher(content) 方法获得一个 Matcher 对象。

  • PatternSyntaxExcption 类:

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

25.2.1 Pattern 类常用方法

  • Pattern.matches(reg, content):整体匹配,输入的字符串是否符合表达式。返回布尔值。

    matcher.matches():整体匹配,字符串是否符合表达式。返回布尔值。前面的方法实际上就是这个方法。

  • Pattern.compile(reg):返回一个指定表达式的 Pattern 对象

  • pattern.matcher(content):返回一个字串的 Matcher 对象

  • matcher.pattern():返回该 Matcher 对象的表达式

    pattern.pattern():返回该 Pattern 对象的表达式

  • matcher.find():尝试查找下一个匹配的序列,返回布尔值

    matcher.find(int):重置该匹配器,从指定索引位置开始重新查找

  • matcher.start():返回本次匹配的字符起始位置的索引

    matcher.end():返回本次匹配的字符结束位置 + 1 的索引

    这个场合,content.substring(matcher.start(), matcher.end()) 就是匹配的字符串

  • matcher.start(int):返回本次匹配的字符的该组内容的起始位置的索引

    matcher.end(int):返回本次匹配的字符的该组内容的结束位置 + 1 的索引

  • matcher.replaceAll(str):替换匹配到的全部内容

    matcher.replaceFirst(str):替换第一次匹配到的内容

    这些场合,返回的字符串才是替换后的字符串。原字符串不变。

25.3 分组、捕获、反向引用

  • 分组(子表达式)

  • 捕获:把正则表达式中,子表达式(分组)的内容保存到内存中以数字编号或显式命名的组里,方便后面引用。以分组的左括号为标志,第一组组号为 1,第二组为 2,以 0 代表整个正则表达式。

  • 反向引用:分组的内容被捕获后,可以在这个括号后使用。这种引用既可以是在正则表达式内部,也可以在外部。内部反向引用 \分组号、外部反向引用 $分组号

    String regular = "(\\w)\\1+";			//即,重复的字母或数字
    Matcher matcher = Pattern.compile(regular).mathcer(content);
    content = matcher.replaceAll("$1");		//这样,就完成了去重

25.4 在 String 中使用正则表达式

  • str.matches(reg):整体匹配
  • str.replaceAll(reg, reg):替换匹配到的全部内容
  • str.split(reg):分割内容

<Java>25 正则表达式
https://i-melody.github.io/2022/03/02/Java/入门阶段/25 正则表达式/
作者
Melody
发布于
2022年3月2日
许可协议