正则表达式高级 ——《精通正则表达式》 +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字节\XUnicodeASCII字符族(来自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)\u00A9Unicode 版权符号\Q...\E不使用元字符和转义序列