10regex正则

本文最后更新于 2021-08-24 11:53:24

Regex正则

一个正则表达式是一种从左到右匹配主体字符串的模式。 “Regular expression”这个词比较拗口,我们常使用缩写的术语“regex”或“regexp”。 正则表达式可以从一个基础字符串中根据一定的匹配模式替换文本中的字符串、验证表单、提取字符串等等。

基本匹配

"the" => The fat cat sat on the mat.
"The" => The fat cat sat on the mat.

元字符

元字符 描述
. 句号匹配任意单个字符除了换行符。
[ ] 字符种类。匹配方括号内的任意字符。
[^ ] 否定的字符种类。匹配除了方括号里的任意字符
* 匹配>=0个重复的在*号之前的字符。
+ 匹配>=1个重复的+号前的字符。
? 标记?之前的字符为可选. 0个或1个
{n,m} 匹配num个大括号之前的字符或字符集 (n <= num <= m).
(xyz) 字符集,匹配与 xyz 完全相等的字符串.
| 或运算符,匹配符号前或后的字符.
\ 转义字符,用于匹配一些保留的字符 `[ ] ( ) { } . * + ? ^ $ \
^ 从开始行开始匹配.
$ 从末端开始匹配.

点运算符 .

".ar" => The car parked in the garage.

字符集 [ ]

  • 方括号用来指定一个字符集。 在方括号中使用连字符来指定字符集的范围。 在方括号中的字符集不关心顺序。 例如,表达式[Tt]he 匹配 theThe

    "[Tt]he" => The car parked in the garage.
    
  • 方括号的句号就表示句号。 表达式 ar[.] 匹配 ar.字符串

    "ar[.]" => A garage is a good place to park a car.
    
  • 一般来说 ^ 表示一个字符串的开头,但它用在一个方括号的开头的时候,它表示这个字符集是否定的。 例如,表达式[^c]ar 匹配一个后面跟着ar的除了c的任意字符。

    "[^c]ar" => The car parked in the garage.
    

重复次数

  • * >=0次

    • *号匹配 在*之前的字符出现大于等于0次。 例如,表达式 a* 匹配0或更多个以a开头的字符。表达式[a-z]* 匹配一个行中所有以小写字母开头的字符串。
    "[a-z]*" => The car parked in the garage #21.
    
    • *字符和.字符搭配可以匹配所有的字符.**和表示匹配空格的符号\s连起来用,如表达式\s*cat\s*匹配0或更多个空格开头和0或更多个空格结尾的cat字符串。
    "\s*cat\s*" => The fat cat sat on the concatenation.
    
  • + >=1次

    • +号匹配+号之前的字符出现 >=1 次。 例如表达式c.+t 匹配以首字母c开头以t结尾,中间跟着至少一个字符的字符串。
    "c.+t" => The fat cat sat on the mat.
    
  • ? 0或1次

    • 在正则表达式中元字符 ? 标记在符号前面的字符为可选,即出现 0 或 1 次。 例如,表达式 [T]?he 匹配字符串 heThe
    "[T]he" => The car is parked in the garage.
    
    "[T]?he" => The car is parked in the garage.
    
  • {} 常用来限定一个或一组字符可以重复出现的次数

    • 表达式 [0-9]{2,3} 匹配最少 2 位最多 3 位 0~9 的数字。
    "[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
    
    • 我们可以省略第二个参数。 例如,[0-9]{2,} 匹配至少两位 0~9 的数字。
    "[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.
    
    • 如果逗号也省略掉则表示重复固定的次数。 例如,[0-9]{3} 匹配3位数字
    "[0-9]{3}" => The number was 9.9997 but we rounded it off to 10.0.
    

特征群 ()

() 中包含的内容将会被看成一个整体

表达式 (ab)* 匹配连续出现 0 或更多个 ab

但如果在 {} 前加上特征标群 () 则表示整个标群内的字符重复 N 次

() 中用或字符 | 表示或。例如,(c|g|p)ar 匹配 cargarpar.

"(c|g|p)ar" => The car is parked in the garage.

或运算符 |

(T|t)he|car 匹配 (T|t)hecar

"(T|t)he|car" => The car is parked in the garage.

转码特殊字符 \

反斜线 \ 在表达式中用于转码紧跟其后的字符。用于指定 { } [ ] / \ + * . $ ^ | ? 这些特殊字符。如果想要匹配这些特殊字符则要在其前面加上反斜线 \

例如 . 是用来匹配除换行符外的所有字符的。如果想要匹配句子中的 . 则要写成 \. 以下这个例子 \.?是选择性匹配.

"(f|c|m)at\.?" => The fat cat sat on the mat.

锚点

^

^ 用来检查匹配的字符串是否在所匹配字符串的开头。

"(T|t)he" => The car is parked in the garage.
"^(T|t)he" => The car is parked in the garage.

$

$ 号用来匹配字符是否是最后一个。

"(at\.)" => The fat cat. sat. on the mat.
"(at\.)$" => The fat cat. sat. on the mat.

简写字符集

简写 描述
. 除换行符外的所有字符
\w 匹配所有字母数字,等同于 [a-zA-Z0-9_]
\W 匹配所有非字母数字,即符号,等同于: [^\w]
\d 匹配数字: [0-9]
\D 匹配非数字: [^\d]
\s 匹配所有空格字符,等同于: [\t\n\f\r\p{Z}]
\S 匹配所有非空格字符: [^\s]
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\v 匹配一个垂直制表符
\p 匹配 CR/LF(等同于 \r\n),用来匹配 DOS 行终止符

断言

断言不会匹配到目标值,只会去判断目标值的前后是否存在指定字符

例如,我们想要获得所有跟在 $ 符号后的数字,我们可以使用正后发断言 (?<=\$)[0-9\.]*。 这个表达式匹配 $ 开头,之后跟着 0,1,2,3,4,5,6,7,8,9,. 这些字符可以出现大于等于 0 次。 匹配其实还是匹配的数字

符号 描述
?= 正先行断言-存在
?! 负先行断言-排除
?<= 正后发断言-存在
?<! 负后发断言-排除

正先行断言?=

表示第一部分表达式之后必须跟着 ?=...定义的表达式

"(T|t)he(?=\sfat)" => The fat cat sat on the mat.

负先行断言

筛选条件为 其后不跟随着断言中定义的格式。

"(T|t)he(?!\sfat)" => The fat cat sat on the mat.

正后发断言

筛选条件为 其前跟随着断言中定义的格式

"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.

负后发断言

筛选条件为 其前不跟随着断言中定义的格式

"(?<!(T|t)he\s)(cat)" => The cat sat on cat.

标志

可以用来修改表达式的搜索结果。 这些标志可以任意的组合使用,它也是整个正则表达式的一部分。

标志 描述
i 忽略大小写。
g 全局搜索。
m 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。

修饰符 g 常用于执行一个全局搜索匹配,即(不仅仅返回第一个匹配的,而是返回全部)。

"/.(at)/" => The fat cat sat on the mat.
"/.(at)/g" => The fat cat sat on the mat.

多行修饰符 (Multiline)

像之前介绍的 (^,$) 用于检查格式是否是在待检测字符串的开头或结尾。但我们如果想要它在每行的开头和结尾生效,我们需要用到多行修饰符 m

例如,表达式 /at(.)?$/gm 表示小写字符 a 后跟小写字符 t ,末尾可选除换行符外任意字符。根据 m 修饰符,现在表达式匹配每行的结尾。

"/.at(.)?$/" => The fat
                cat sat
                on the mat.
"/.at(.)?$/gm" => The fat
                  cat sat
                  on the mat.

惰性匹配

贪婪匹配与惰性匹配 (Greedy vs lazy matching)

"/(.*at)/" => The fat cat sat on the mat. 
"/(.*?at)/" => The fat cat sat on the mat. 

正则替换字串

1
2
3
4
5
6
7
8
9
abcde_123

匹配:
(\S+)_(\d+)

替换:保留abcde_ ,数字替换为aa
$1_aa 或者是 \1_aa
$1或\1表示第一个括号匹配到的内容
$0表示匹配到的一整行

正则替换大小写

1
2
3
4
5
6
7
8
9
10
11
\U 将匹配项转为大写(Upper)
\L 将匹配项转为小写(Lower)
\E 终止转换,转换从\U或\L开始到\E结束之间的字母大小写类型.(End)

abcde_123
匹配:
(\S+)_(\d+)
替换:将abcde替换为大写,将123替换为小写的ff
\U\1\E_ff

注意:如果没有\E,后面的ff也会被替换为大写

java中正则Demo

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
// 去除单词与 , 和 . 之间的空格
String str = "Hello , World .";
String pattern = "(\\w)(\\s+)([.,])";
// $0 匹配 `(\w)(\s+)([.,])` 结果为 `o空格,` 和 `d空格.`
// $1 匹配 `(\w)` 结果为 `o` 和 `d`
// $2 匹配 `(\s+)` 结果为 `空格` 和 `空格`
// $3 匹配 `([.,])` 结果为 `,` 和 `.`
System.out.println(str.replaceAll(pattern, "$1$3")); // Hello, World.
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  //Java 中可以在小括号中使用 ?<name> 将小括号中匹配的内容保存为一个名字为 name 的副本。
//notepad++不行
public static void main(String[] args) {
String str = "@wjj 你好啊";
Pattern pattern = Pattern.compile("@(?<first>\\w+\\s)"); // 保存一个副本
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
System.out.println(matcher.group(1));
System.out.println(matcher.group("first"));
}
}

/**
@wjj
wjj
wjj
**/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//java中的标志
// i , g , m
public static void main(String[] args) {
String str = "1990\n2010\n2017";
// 这里应用了 (?m) 的多行匹配模式,只为方便我们测试输出
// "^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$" 为判断 1990-2017 正确的正则表达式
Pattern pattern = Pattern.compile("(?m)^1990$|^199[1-9]$|^20[0-1][0-6]$|^2017$");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
}

// Pattern pattern = Pattern.compile("(?i)\\w+"); // 推荐写法

常用正则表达式

汉字:^[\u4e00-\u9fa5]{0,}$
Email地址:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
域名:^((http:\/\/)|(https:\/\/))?([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}(\/)
手机号: ^([1][3,4,5,6,7,8,9])\d{9}$
IP地址:\d+\.\d+\.\d+\.\d+


10regex正则
https://jiajun.xyz/2020/10/22/java/java基础/10regex正则/
作者
Lambda
发布于
2020年10月22日
更新于
2021年8月24日
许可协议