美文网首页
正则表达式的学习

正则表达式的学习

作者: 头发依然在 | 来源:发表于2017-11-29 15:59 被阅读64次

    第一次接触正则表达式的时候一脸懵逼,相信很多人都和我一样的感受。万幸最近找到一篇文章,学到很多,因此记录一下。

    概念

    正则表达式描述了一种字符串的匹配模式,可以用来检查一个串是否含有某种子串,将匹配的字串做替换或者取出符合匹配条件的字串。
    它是由普通字符(a-z 、A-Z 、 0-9 等)以及特殊字符组成的规则,它作为一个模板,将其他字符串与之进行匹配,得到匹配结果(true/false)。

    特点

    正则表达式是简单的,同时又是复杂,特性:简单而又功能强大,因而就决定了它的复杂。

    普通字符

    首先来认识一下普通字符,字母、数字、汉字、下划线以及没有特殊含义(后面会有解释)的标点符号都是普通字符,在用正则匹配时,匹配的就是字符本身。

    举例:

    表达式 匹配
    "c" 在匹配字符串"abcdefg"时,匹配到字符"c",匹配成功
    "abc" 在匹配字符串"abcdefg"时,匹配到字符"abc",匹配成功
    "我" 在匹配字符串"我爱学习"时,匹配到字符"我",匹配成功

    转义字符

    不是原来的字面意思,转为其他含义。
    如:

    表达式 说明
    \f 匹配一个换页符
    \n 匹配一个换行符
    \r 匹配一个回车符
    \s 匹配一个任意空字符
    \S 匹配一个任意非空字符

    还有一些下面的特殊字符,在前面加"",表示匹配字符本身。

    特殊字符

    所谓特殊字符,就是有特殊含义的字符,在正则中含义是固定的。

    表达式 说明
    ^ 这个符号有两种意思,下面会有具体解释
    $ 匹配的字符的位置在末尾
    . 可以匹配除换行符以外的任意字符

    还有其他特殊字符,下面会分类进行解释和如何使用。对于这些特殊字符,在字符前加"",在匹配时匹配的是字符本身,如:"^"、 "$"、 "." 其实匹配的是"^"、 "$"、 "."。

    表达式

    1、匹配多个字符

    字符的一对一匹配很好解释和理解,但是还有一些其他的书写方式,用于一对多的匹配,即一个字符匹配多个字符中的任意一个,就表示匹配成功。虽然可以匹配其中多个字符,但是只能是一个字符。

    表达式 说明
    \d 0-9任意一个数字,只能是一个
    \w 字母A-Z a-z 数字0-9 下划线_ 中的任意一个,只能是一个
    \s 任意一个空字符

    表达式的理解比较抽象,我们举例说明:
    表达式 "\d\d" 在匹配 "123" 时,匹配成功,匹配到的内容是"12"。因为"\d"表示任意一个0-9的数字,所以两个"\d"就表示匹配两个连续的数字,即“12”。
    表达式 "a.\w" 在匹配 "55a5b556"时,匹配成功,匹配的内容是"a5b"。表达式的意思是连续三个字符,第一个是"a",第2个是任意非换行符的字符,第3个是字母或数字或下划线,即"a5b"。当然,如果字符中有"acc"、"a55"、"a.5"也表示匹配成功。

    2、匹配自定义的多个字符

    要匹配自定义的多个字符就要用到集合符合[ ],可以将要匹配的多个字符放在里面,如:[abc345]。
    如果在集合的字符之前加"",如[abc345],就表示匹配除了a、b、c、3、4、5以外其他任意一个字符。

    表达式 说明
    [a1b2c3] 可以匹配a、b、c、1、2、3中的任意一个
    [^a1b2c3] 可以匹配a、b、c、1、2、3以外的任意一个字符
    [a-f5-9] 可以匹配a-f之间和5-9之间的任意一个字符
    [^a-f5-9] 可以匹配a-f以外或5-9以外的任意一个字符

    举例:
    表达式"[mq][abc][123]" 在匹配"mb3k56a"时,匹配成功,匹配到的内容是"mb3"。
    表达式"[^mq][abc]"在匹配"mb3k56a"时,匹配成功,匹配到的内容是"6a"。表达式的意思是匹配两个字符,第一个不是m 不是q,第2个字符是a b c 三个字符中的一个。

    3、匹配次数设置

    匹配次数就是重复匹配的次数。有些字符比较长,对于相同规则的可以进行简化。比如上面提到的"\d\d"就可以简化成"\d{2}",即两个连续的数字,因为第一个是数字,匹配两次,即匹配两个字符,第2个也是数字。

    表达式 说明
    {n} 匹配固定次数
    {m,n} 至少匹配m次,最多匹配n次,(m<n)
    {m,} 至少匹配m次
    * 匹配任意次
    ? 匹配0次或匹配1次
    + 至少匹配1次

    举例:
    表达式"\d{11}" 可以匹配连续的11个数字,{11}表示匹配11次,即11个字符
    表达式"\d+.\d" 在匹配"it is ¥12.5"时,匹配成功,匹配到的内容"12.5",表达式的含义:小数点前至少有一个数字,小数点后有一个数字
    表达式"go{2,8}gle" 可以匹配"goooooogle",{2,8}表示至少匹配两次,最多匹配8次,所以6个"o"能匹配上。

    4、其他意义抽象的特殊符号
    表达式 含义
    "^" 与字符串开始的地方进行匹配,但不代表任何字符,也不匹配任何字符
    "$" 与字符串结束的地方匹配,但不代表任何字符,也不匹配任何字符
    "\b" 匹配一个字符串的边界,也就是一个位置,左右两边一边是字符,一边不是字符,是一个单词的边界,本身不代表任何字符,也不匹配任何字符

    还是举例说明:
    a、表达式"^aaa" 在匹配"aaabbccc"是匹配成功,因为"^"要求三个连续的"a"必须在字符串的开始的位置,在匹配"xxxaaaxxx"时,匹配失败,因为"aaa"不在字符串开始的位置。
    b、表达式"$bbb"在匹配"aaaccbbb"时匹配成功,因为"$"要求三个连续的"b"必须在字符串结束的位置,在匹配"xxxbbbxxxx"时,匹配失败,因为"bbb"不在字符串结束的位置。
    c、表达式".\b."在匹配"@@@abc"时匹配结果:"@a",因为"."表示任意非换行符的字符,"\b"是一个限制条件,要求左右两边一边是字符,一边不是字符,所以就匹配到"@a"。
    d、进一步说明,"\b"和"^"、"$"本质是一样的,符号本身不匹配任何字符,都是限制条件。
    举例"\bend\b"在匹配"weekend,endfor,end"时,匹配成功,因为表达式中的"e"和"d"都是字符,而"\b"要求匹配的位置一边是字符,一边不是,所以"e"左边必须不是字符,"d"右边必须不是字符,所以匹配到最后的"end",因为之后最后的"end"左右两侧才不是字符,而是字符的边界。

    5、表达式优先级设置
    表达式 含义
    "|" 或的意思,两者符合一个就行
    "()" 一组括号,两层含义:①、在被修饰匹配次数的时候,括号中的表达式可以作为一个整体被修饰;②、取匹配结果的时候,括号中的表达式匹配的内容可以作为一个整体被单独得到

    举例:
    表达式"Tom|Jack"在匹配字符串是时"I'm Tom,he is Jack" 匹配到的数据是"Tom",匹配下一个时匹配的是"Jack"。
    表达式"(go\s)+"在匹配"Let's go go go!"时,匹配到的内容是"go go go","\s"表示任意一个空白字符," * "表示任意次数,所以"( )"匹配到的内容是"go "[ go后面是有空格的 ],"+"表示最少出现一次,所以可以匹配多次"go ",所以匹配到到"go go go"
    表达式"¥(\d+.\d
    )"在匹配"$12.9,¥20.5"时,匹配成功,匹配到"¥20.5"。

    6、反向引用\1、\2......

    表达式在匹配时,经常使用"( )"将其作为一个整体进行匹配,同时又将匹配到的结果保存下来。而在实际应用开发中,在匹配到结果之后,我们在后边的表达式中还想用,简单的方法是将其重新写一下,但是如果是复杂的,再重新写就比较麻烦,而且如果多次使用的话就更麻烦,针对这个问题,正则给了一个简单的使用方法:反向引用。
    引用方法是""再加上数字序号,数字序号的意思是表示引用第几个括号,如"\1"引用第一个括号匹配的值,"\20"引用第20个括号匹配的值........以此类推,如果一个括号内包含另一对括号,则从外向内、从做向右编号。
    举例:
    表达式"('|")(.?)(\1)"在匹配" 'Hello',"world" "时匹配到" 'Hellow' ",下次匹配时匹配到" "World" ",其中"(\1)"表示"('|")"匹配到的内容。
    表达式"(\w)\1{4,}"在匹配"aa bbbb ccccc 111121111 999999999"时匹配到"ccccc",再次匹配时匹配到"999999999","(\w)"最少出现5次。
    表达式"<(\w+)\s
    (\w+(=('|").?\s)>.?</\1>)"在匹配" <td id='td' style="bgcolor.white"></td>"匹配成功,如果<td></td>不配对,则匹配失败。
    上图:

    image.png
    图中的序号就是在引用时的顺序,方便大家理解。
    7、正则表达式的高级规则(贪婪模式和非贪婪模式)

    贪婪模式:
    在使用次数修饰符修饰表达式的时候,有几种表示方法可以使同一个表达式能够匹配多次,比如"{m}"、"{m,n}"、"?"、" * ",这种重复的匹配次数的表达式在匹配过程中,总是尽可能的多匹配,这种模式就是贪婪模式。
    举例:针对字符串"dxxxdxxxd"

    表达式 解释
    (d)(\w+) "(\w+)"将匹配字符"d"之后的所有字符,即"xxxdxxxd"
    (d)(\w+)(d) "(\w+)"将匹配第一个"d"和最后一个"d"之间的所有字符,即"xxxdxxx",虽然"(\w+)"也能匹配上最后一个"d",但如果匹配了最后一个"d",则表达式就不能匹配成功,所以"(\w+)"会让出最后的一个"d",从而促使表达式匹配成功

    由此可见,"\w+"在匹配的时候总是尽可能多的匹配符合它规则的字符,虽然第2个举例中它没有匹配最后的一个"d",但那是为了让整个表达式能够匹配成功;同理,在使用" * "、"{m,n}"时都是尽可能多的去匹配,在使用"?"进行可有可无的匹配时也是尽可能要匹配,这就是贪婪模式。

    非贪婪模式:(容易满足)
    在修饰匹配次数的符号后加上符号"?",则可以使匹配次数不定的表达式尽可能少的匹配,只要满足规则就行,不需要对整个字符串匹配,在可有可无的进行匹配时选择不匹配,这种匹配模式称为“非贪婪模式”,当然如果在匹配中少匹配会导致匹配失败的话,还是会进行贪婪模式的多匹配,以使表达式匹配成功。

    非贪婪模式的匹配原则:如果少匹配能是表达式匹配成功,则少匹配;如果少匹配时匹配失败,则进行多匹配,保证匹配成功。
    举例:针对字符串"dxxxdxxxd"

    表达式 解释
    (d)(\w+?) 根据非贪婪模式的原则,"\w+?"尽可能少的匹配,所以只能匹配到一个字符,即字符"d"后面的"x"
    (d)(\w+?)(d) 根据非贪婪模式的原则,尽可能少的匹配,所以"\w+?"能匹配到第一个"d"和第二个"d"之间的字符"xxx",如果第二个"d"改成其他字符,则匹配到的是第一个和最后一个之间的所有字符

    外篇:(一起共同学习进步)
    QQ群:541144061

    QQ群.png

    相关文章

      网友评论

          本文标题:正则表达式的学习

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