美文网首页
正则表达式高级

正则表达式高级

作者: 林万程 | 来源:发表于2019-08-04 23:41 被阅读0次

    正则表达式高级
    ——《精通正则表达式》
    +Java/Go/Python官方文档
    +多年经验
    +实验结果
    知识整理

    [TOC]

    第3章 正则表达式的特性和流派概览

    常用的元字符和特性 102

    基本语法
    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()

    • 分组并捕获(...)
    • 正则反向引用(Java Python)\n(golang貌似未提供)
    • 字符反向引用(Java golang)$n
    • 字符反向引用(Python)\n \g<n>
    • 命名捕获(Java)(?<name>...)
    • 正则反向引用(Java)\k<name>
    • 字符反向引用(Java golang)${name}
    • 字符反向引用(golang)$name
    • 命名捕获(Python golang)(?P<name>...)
    • 正则反向引用(Python)(?P=name)
    • 字符反向引用(Python)\g<name>
    • 多选结构...|...
    • 仅分组不捕获(?:...)
    • 固化分组(golang不支持)(?>...)
    • 注释(宽松排列时 golang不支持)# ...

    Java不支持:

    • 条件(Python)(?(n/name)...|...)
    • 代码条件(?... ...|...)
    • 嵌入式注释(?#...)
    • 嵌入式代码(?{...})
    • 动态表达式(??{...})

    边界

    锚点:

    • 行始^
    • 文始\A \G
    • 行末$
    • 文末\Z \z
    • 单词边界\b
    • 非单词边界\B

    环视结构(零长度断言,golang不支持):

    • 顺序环视
      • 左边是A:(?<=A)
      • 左边不是A:(?<!A)
    • 逆序环视
      • 右边是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
    • Unicode按规则等价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字节
    • \XUnicode

    ASCII字符族(来自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

    https://godoc.org/regexp

    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不使用元字符和转义序列

    相关文章

      网友评论

          本文标题:正则表达式高级

          本文链接:https://www.haomeiwen.com/subject/bztydctx.html