Java 正则表达式 Java Regular Expression (RegExr or regex)

Java Class: Pattern and Matcher Noting!

find() 在输入字符串中查找与 正则表达式 匹配的 子序列. (此方法可以多次调用, 以查找输入字符串中的多个匹配子序列)
group() 返回 整个 匹配的子串. group(0)group() 方法等价. (在正则表达式中, 组号是从 1 开始计数的, 因此 Matcher.group(0) 不是用来获取第 0 组匹配的子串, 而是用来获取整个匹配的子串)
Matcher#matches()整个输入字符串正则表达式 进行匹配. (此方法只会匹配一次, 只会匹配整体, 如果匹配失败, 则不能再调用此方法)
如果只使用 matches() 方法, 可以直接调用 String#matches, 能省略中间部分代码

0 Java 正则匹配

	String regex = "20\\d\\d";
    System.out.println("2019".matches(regex)); // true

. any 正则表达式a.c中间的.可以匹配一个任意字符且仅限一个字符(不包括0个)
\\d number \\D no number
\\$ 匹配特殊字符 $,正则表达式有特殊字符,那就需要用 \ 转义,因为 \ 也是Java字符串的转义字符,两个\\实际上表示的是一个\
& 不是特殊字符

1 基础

  • 双斜杠 \\

Java 中正则表达式中则需要有两个反斜杠 \\ 才能被解析为其他语言中的转义作用

序列 \\\\ 匹配 \\\\( 匹配 (. \\ 表示将下一字符标记为特殊字符文本反向引用八进制转义符

根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 “\b” 与单个退格字符匹配,而 “\\b” 与单词边界匹配。字符串字面值 “\(hello\)” 是非法的,将导致编译时错误;要与字符串 “hello” 匹配,必须使用字符串字面值 “\\(hello\\)”。

  • ^表示开头,$表示结尾
// 1. 使用括号()来进行分组匹配
Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
Matcher m = p.matcher("010-12345678");
// 2. 只看是否完全包含的情况 (只匹配一次)
if (m.matches()) {
    String g1 = m.group(1);
    String g2 = m.group(2);
}
// 3. 引擎会把匹配到的字符串去掉,方便下次一匹配(find()),这里是重置
m.reset();
while(m.find()){
	String group = m.group(); // equal m.group(0); 获取当前匹配的子串
	group.soutv;
}
// 4. 从开始的位置查找
m.lookingAt();
// 5. 只看是否包含子串的情况 (只匹配一次)
if(m.find()){
	m.start() + "-" + m.end() // 当前匹配的子串的 开始位置, 结束位置
}

1.1 特殊字符

特殊字符很重要, 特别是在 java 中 regex 字符串有两层转义的情况.

必需在表示正则表达式的字符串文字中使用双重反斜杠,以保护它们免受Java字节码编译器的解释

反斜杠可以在非字母字符之前使用,无论该字符是否是未转义构造的一部分

\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符

所有能转义的符号 \ ^ $ * + ? { . ( ) [ 都是特殊字符

e.g. ${ 是; 而普通字母 dw 不是

Pattern.compile("\\"); // 2 literal: "\" 匹配: ERROR 因为在正则里面单个 \ 代表"转义字符" 后面必须接字符, 哪怕是空格 ("\\ " 代表 空格, idea会提示不需要转义:"redundant escape")
Pattern.compile("\\\\"); // 4 literal: "\\" 匹配: "\" 这时 \ 后面没有接转义字符, \\ -> \
Pattern.compile("\\\\\\$\\\\\\{"); // 6 literal: "\\\$\\\{" 匹配: "\$\{" 这时 \ 后面接了转义字符 
Pattern.compile("\\\$\\{"); // 3 & 2 literal: "\$\{" 匹配: "${"
  • 为什么 $ 需要3个 { 只需 2个呢?

因为 $ 代表结尾符号, 只用一个 $ 就行, 而 \$ 会在Java层面转义为 $, 在加上前面的 \\ 才是 正则里面的 \$, 字面意义的 $

  • 为什么 4 个 \\\\ 才代表 regex 中的一个 \ 字面字符呢

Java 字节码编译器会自动解释, 所有字符串中的转义字符, 如 \n. 实际虚拟机拿到的字符, 总是转义后的, 然后在正则中还需要表示转义字符, 就只有套娃了

不知道 \ 属于哪个部分?
    在idea中, 双击 \ 就行了

1.2 转义字符

\\w word \\W no words 等价与 [A-Za-z0-9_]
\s 匹配一个空格字符或tab字符

  • 用于重复匹配的修饰符:
    • ? 可以匹配0个或一个字符
    • + 可以匹配至少一个字符
    • {n} 精确指定n个字符。{n,}代表没有上限
    • * 可以匹配任意个字符
# 范围由小到大
? 0~1
+ 1~n
{n} n个
* 任意个 0~n
# 在 aop 中
*  一层 任意字符
.. 多层 任意参数(0-多个参数)
  • 括号: 捕获组 (group)

特殊组group(0) 总是代表整个表达式

  1. 普通捕获组 (1)(2(3)(4))
  2. 命名捕获组 (?<name>pattern) (命名的捕获组同样也可以使用编号获取相应值)
    e.g. (?<year>\\d{4})-(?<md>(?<month>\\d{2})-(?<date>\\d{2}))
  3. 非捕获组 (?:pattern)
    在左括号后紧跟 ?:,而后再加上正则表达式,构成非捕获组 (?:Expression)。
    (?=pattern)(?!pattern) 也是非捕获匹配

1.3 非捕获元 ?=、?!、?<=、?<!

  • 先行断言(lookahead)
    exp1(?=exp2):查找 exp2 前面的 exp1
  • 后行断言(lookbehind)
    (?<=exp2)exp1:查找 exp2 后面的 exp1
  • 先行断言(lookahead)
    exp1(?!exp2):查找后面不是 exp2exp1
  • 后行断言(lookbehind)
    (?<!exp2)exp1:查找前面不是 exp2exp1

先行断言(lookahead) 和后行断言(lookbehind)它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为"零宽"。

1.4 反向引用

content=Pattern.compile("(.)\\1+").matcher(content).replace("$1");

2 非贪婪匹配

正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,在规则后面加个?即可表示非贪婪匹配(注意使用括号括起来,如 (\d+?)(0*) )
(\d??)(9*) 匹配 “9999”,因为使用了非贪婪,所以第一组匹配了“”空字符串,注意\d?表示匹配0个或1个数字,后面第二个?表示非贪婪匹配
String.split()方法传入的正是正则表达式
String.replaceAll(),它的第一个参数是正则表达式,第二个参数是待替换的字符串。传入的第二个参数可以使用$1、$2来反向引用匹配到的子串(必须使用括号分组)

3 实例

判断是否包含大小写字母,数字和特殊字符
String regexZST = "^(?![A-Za-z0-9]+$)(?![a-z0-9\\W]+$)(?![A-Za-z\\W]+$)(?![A-Z0-9\\W]+$)[a-zA-Z0-9\\W]{8,}$";
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内)[^\x00-\xff]

4 驼峰转下划线 正则

可以在 idea 等搜索框中便捷的使用

正则之驼峰转下划线

记住: upper case, lower case, end

序号符号含义
1\l下个字符小写
2\u下个字符大写
3\L接着的字符均小写直到 \E
4\U接着的字符均大写直到 \E
5\E结束 \L, \E 和 \Q
6\Q在转义字符前加上 \Q, 如 \Q$

1. 概要

  1. 小写 \l 代表接下来的 1 个字符
  2. 大写 \L 代表后面 所有 字符
  3. 使其小写 Lower \L
  4. 使其大写 Upper \U
  5. 控制结束 End \E

$1对应的是正则中第一个元组(\d{3})匹配到的结果, $0代表匹配到的整个字符

2. 使用

开启正则匹配模式

  1. _([a-z]) 替换成 \U$1\E , 可以完成下划线转驼峰
  2. List<(.*?)> 替换成 $1, 完成去掉外层
  3. ([A-Z]) 替换成 \L$1\E 大写 -> 小写
  4. ([a-z]) 替换成 \U$1\E 小写 -> 大写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值