• 正则表达式


    基础

    • 需要谨记的3个字母

    d

    匹配数字

    w

    匹配字母、数字、下划线

    s

    匹配空白符(例如空格、换行符、制表符等)

    大写表示匹配其相反的东西,如:D 匹配非数字字符,S匹配非空白字符

     

    • 常用的匹配字符

    [0-9]

    匹配在此区间的数字,同d

    [a-zA-Z]

    匹配在此区间的字母,可以多个区间一起

    [x.|9\]

    匹配在中括号内的字符,里面的都是普通字符没其他含义,除斜杠比较特殊需转义

    [^a8]

    匹配除中括号内字符之外的字符,和上面3个字母大写匹配其相反的东西一样的道理

    hello

    匹配常规字符串

    ^hello

    匹配行首的hello

    hello$

    匹配行末的hello

    hello|world

    匹配hello或者world(正则中没有与运算)

    .

    匹配除换行符( 、 )之外的任意字符

    [u4e00-u9fa5]

    匹配中文字符

    [sS]

    匹配任意字符(随便两个互补区间都可以表示任意字符)

     

    • 表示字符数量的描述符(描述前面子表达式的匹配数量)

    *

    零次或多次

    +

    一次或多次

    ?

    零次或一次

    {n}

    整数n

    {n,m}

    n~m次,包含nm

    {n,}

    n次以上,包含n

    默认是描述前面一个字符,如果是多个字符的子表达式,需要括号括起来。

    如:(pattern)*     th(is|at)       括号别有用处,后面会讲到

     

    进阶

    • 获取匹配与非获取匹配

    (pattern)

     

    这里用括号将匹配子表达式括起来,从匹配结果来看加括号不影响正常匹配。

    加括号主要是为了获取该子表达式匹配到的内容

    获取匹配,怎么用我们后面会讲到

    (?:pattern)

    如果我们加括号只是为了圈定一串子表达式,而不用获取匹配到的内容。

    上面的例子我们最好这样  th(?:is|at),等同于this|that

    非获取匹配

    hello(?=world)

    如果一字符串包含多处hello,只匹配后面跟着worldhello,匹配结果不包含world

    例如,"Windows(?=95|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows98"中的"Windows"

    非获取匹配

    hello(?!world)

    同理,只匹配后面没跟着worldhello,匹配结果不包含world

    非获取匹配

    (?<=hello)world

    如果一字符串包含多处world,只匹配前面跟着helloworld,匹配结果不包含hello

    例如,"(?<=95|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"98Windows"中的"Windows"

    非获取匹配

    (?<!hello)world

    同理,只匹配前面没跟着helloworld,匹配结果不包含hello

    非获取匹配

     

    • 非贪婪匹配

    举个例子:"hello world and hi world"  我们需要匹配其中的"hello world""hi world"

    1. 我们可以这样子h.*world,但是我们运行后发现匹配到的结果是"hello world and hi world",这结果也没毛病,确实符合我们写出来的正则表达式。
    2. 如何得到我们想要的结果呢,我们这样子h.*?world,就能匹配到"hello world""hi world"

    贪婪匹配:尽可能匹配最长的字符串

    非贪婪匹配:尽可能匹配最短的字符串

    个人对非贪婪匹配的理解是:从左往右匹配到符合正则的最短结果,返回结果并继续往后匹配下一结果。

     

    • 扩展(思考)

    匹配typepasswordinput标签: <input type=radio name=xxx><input type=password name=yyy><input type=txt name=zzz>

    1. <input.*password.*>  匹配得到  <input type=radio name=xxx><input type=password name=yyy><input type=txt name=zzz>
    2. <input.*password.*?>  匹配得到  <input type=radio name=xxx><input type=password name=yyy><input type=txt name=zzz>
    1. <input((?!input).)*password.*?>匹配得到<input type=radio name=xxx><input type=password name=yyy><input type=txt name=zzz>

    第一步写出匹配的轮廓,第二步使用非贪婪匹配排除掉后面部分,第三步inputpassword之间的字符串排除input

     

    个人对((?!input).)*的理解:

    1. (?!input)i 匹配所有位置的‘i’,但不包括input开头的‘i’,即后面跟着nputi都不匹配。
    2. (?!input).  匹配任意字符(点的作用),但不包括input开头的‘i’。
    3. ((?!input).)*  匹配零个或多个(2)中的字符,既然input开头的‘i’被排除了,那么也就不存在input字符串了。

     

    应用

    java演示group一些特殊用法

    • 获取匹配

    public static void main(String[] args) {

    String str = "Her name is John, Her age is 18";

    Pattern pattern = Pattern.compile("Her name is (\w+), Her age is (\d+)");

    Matcher matcher  = pattern.matcher(str);

    matcher.groupCount(); // 正则表达式中"获取匹配"的数量

    while (matcher.find()) {

    System.out.println(matcher.group());   // 输出整条正则表达式匹配到的内容

    System.out.println(matcher.group(1) + " " + matcher.group(2));  // 输出括号中子表达式匹配到的内容

    }

    }

    结果:

    Her name is John, Her age is 18

    John 18

     

    • 给group取别名,通过别名获取匹配(不影响表达式的正则匹配)Java 7+开始支持

    Pattern pattern = Pattern.compile("Her name is (?<name>\w+), Her age is (\d+)");

    matcher.group(name);

     

    • 在正则表达式中引用groupName匹配到值,\k<groupName>表示groupName表达式匹配到的值

    Pattern pattern = Pattern.compile("Hisname is (?<name>\w+), Her name is (\k<name>)");

    如,匹配他和她名字相同的字符串:His name is John, Her name is John

     

    • 在替换函数中引用groupName匹配到的值,${groupName}

    "His name is John".replaceAll("(?<name>\w+)", "[${name}]");

    结果:[His] [name] [is] [John]

     

    linux命令grep使用正则

    • 我们知道grep命令的 -E 参数是将样式延伸的正则表达式来使用,但是它并不支持(?=pattern)和groupName这种用法。

    这时我们使用 -P 代替之,表示让grep使用perl的正则表达式语法,因为perl的正则更加多元化,能实现更加复杂的场景

    echo ==HelloWorld== | grep "Hello(?=World)" -P    

    输出:==HelloWorld==

     

    • 拓展一下,因为grep命令匹配到一段就会整行输出,-o可以只输出匹配到的部分

    echo ==HelloWorld== | grep "Hello(?=World)" -Po

    输出:Hello

     

    • 再拓展一下,grep命令默认不支持跨行匹配,-z将输入内容作为行的合集,每个集合以空字节作为结束

    我理解-z是将多行的输入内容看作一行,其中换行符也在一行当中,当作普通字符。

    echo -e "==Hello World==" | grep "H[sS]*d" -Pz

    输出:==Hello

     World==

     

    python使用正则

     

     

    练习/训练

    http://tool.chinaz.com/regex/

     

  • 相关阅读:
    JS 缓冲运动 带运动的留言本 小案例
    ===>===>===>特色思TERSUS元件学习整理
    TERSUS无代码开发(笔记29)-分页(转载)
    TERSUS无代码开发(笔记28)-英文日期改成中文日期设置
    TERSUS无代码开发(笔记27)-按钮加图标
    TERSUS无代码开发(笔记26)-复杂表格中字体通过逻辑设置颜色
    TERSUS无代码开发(笔记25)-弹窗的样式设置
    TERSUS无代码开发(笔记24)-排序显示和高级查询
    TERSUS无代码开发(笔记23)-数据库字段设置
    TERSUS无代码开发(笔记22)-利用CSS制作一个悬浮子菜单(转载)
  • 原文地址:https://www.cnblogs.com/zhangzongjian/p/12657506.html
Copyright © 2020-2023  润新知