正则表达式高级 ——《精通正则表达式》 +Java/Go/Python官方文档 +多年经验 +实验结果 知识整理
[TOC]
基本语法 https://www.runoob.com/regexp/regexp-metachar.html
{n}
{n,}
{n,m}
*
同{0,}
+
同{1,}
?
同{0,1}
?
则忽略优先(非贪婪,越少越好)+
则占有优先(类似固化分组, golang不支持),
匹配了就不会还回去,例如
用.*+c
匹配abc
,
.*
会匹配优先地匹配到abc
三个字符,
如果没有+
时发现匹配失败就会回溯到.*
匹配两个的情况,这时匹配成功;
而有+
就占有不还回去了,匹配失败。"abc".replaceAll("a(.*)c", "s$1"); // sb
"b2b".replaceAll("(.*)2\\1", "s$1"); // sb
"b2b".replaceAll("(?<a>.*)2\\k<a>", "s${a}"); // sb
Pattern p = Pattern.compile("a(?<a>.*)c");
Matcher m = p.matcher("abc");
while (m.find()) {
System.out.println(m.group(1)); // b
System.out.println(m.group("a")); // b
}
反向引用组编号n为0代表全部,同m.group()
(...)
\n
(golang貌似未提供)$n
\n
\g<n>
(?<name>...)
\k<name>
${name}
$name
(?P<name>...)
(?P=name)
\g<name>
...|...
(?:...)
(?>...)
# ...
Java不支持:
(?(n/name)...|...)
(?... ...|...)
(?#...)
(?{...})
(??{...})
锚点:
^
\A
\G
$
\Z
\z
\b
\B
环视结构(零长度断言,golang不支持):
(?<=A)
(?<!A)
(?=A)
(?!A)
"abc".replaceAll("(?<=a)b(?=c)", ""); // ac
查找时用捕获比环视更容易阅读
通用常用
(?i)
不区分大小写CASE_INSENSITIVE
(Java 轻微影响性能)(?m)
多行模式(^
和$
匹配整个字符串的头尾)MULTILINE
(?s)
点号通配模式(.匹配任意字符)DOTALL
Java
(?idmsuxU-idmsuxU)
(?idmsux-idmsux:X)
(?u)
Unicode不区分大小写UNICODE_CASE
(影响性能)(?x)
宽松排列和注释(忽略空白和#后的内容)COMMENTS
(?d)
Unix行模式(只有\n
)UNIX_LINES
CANON_EQ
(影响性能)\Q...\E
不使用元字符和转义序列LITERAL
(1.5+)(?U)
启用预定义和POSIX字符类UNICODE_CHARACTER_CLASS(1.7+,影响性能)Python
(?aiLmsux-imsx:…)
(?a)
仅ASCII(?L)
语言依赖其他
(?o)
编译一次(提升性能,Perl)(?U)
忽略优先模式交换x*
和x*?
...的含义(golang)也可以这样用:(?-i)
(?i:...)
(?-i:...)
Pattern p = Pattern.compile("a(?i)b(?-i)c(?i:d)");
Matcher m = p.matcher("aBcD");
Pattern p = Pattern.compile("a", Pattern.CASE_INSENSITIVE);
.
换行符外任意字符[...]
字符组(元字符不需转义)
如[a-z]
匹配小写字母[^...]
不包含Perl字符族:
\d
同[0-9]
\D
同[^0-9]
\w
同[A-Za-z0-9_]
\W
同[^A-Za-z0-9_]
\s
同[ \t\n\v\f\r]
\S
同[^ \t\n\v\f\r]
\C
字节\X
UnicodeASCII字符族(来自golang):
[[:alnum:]]
字母数字同[0-9A-Za-z]
[[:alpha:]]
字母同[A-Za-z]
[[:ascii:]]
ASCII同[\x00-\x7F]
[[:blank:]]
空白[\t ]
[[:cntrl:]]
控制[\x00-\x1F\x7F]
[[:digit:]]
数字[0-9]
[[:graph:]]
图形[!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_
{|}~][[:lower:]]小写
[a-z][[:print:]]可打印
[ -~] == [ [:graph:]][[:punct:]]标点
[!-/:-@[-{-~]
[[:space:]]
空字符[\t\n\v\f\r ]
[[:upper:]]
大写[A-Z]
[[:word:]]
字符[0-9A-Za-z_]
[[:xdigit:]]
十六进制[0-9A-Fa-f]
Unicode组:
\p{}
Unicode 区块/属性/分类,如java汉字
"Hi,你好!".replaceAll("[^\\p{JavaIdeographic}]", ""); // 你好
Character.isIdeographic(int codePoint) // CJKV(中文,日文,韩文和越南文)表意文字
https://docs.oracle.com/en/Java/Javase/12/docs/api/Java.base/Java/util/regex/Pattern.html
golang汉字
package main_test
import (
"fmt"
"regexp"
)
func ExampleFindAllString() {
r := regexp.MustCompile(`[\p{Han}]+`) // 汉字
split := r.FindAllString("你好,中国!", -1)
for _, s := range split {
println(s) // 不计入output
fmt.Println(s)
}
// Output:
// 你好
// 中国
}
https://studygolang.com/static/pkgdoc/pkg/regexp.htm
https://godoc.org/regexp/syntax
python汉字
# coding=utf-8
import re
if __name__ == "__main__":
print(re.findall(r'[\u4e00-\u9fa5]+', '你好,中国!'))
https://docs.Python.org/zh-cn/3/library/re.html#contents-of-module-re
\a
警报同\x09
\cI
\b
退格同\x09
\cI
\e
退出同\x09
\cI
\t
制表同\x09
\cI
\n
换行同\x0a
\cJ
\v
直表同\x0b
\cK
\f
分页同\x0c
\cL
\r
回车同\x0d
\cM
\*
\07
\77
0377
八进制(带0是Java特殊)\xFF
\uFFFF
十六进制\x{10FFFF}
十六进制(golang)\u00A9
Unicode 版权符号\Q...\E
不使用元字符和转义序列