美文网首页
正则表达式

正则表达式

作者: 董成鹏 | 来源:发表于2018-10-12 17:29 被阅读0次

    常见的元字符

    • \b 不消耗任何字符,匹配单词的开始或者结尾
    • . 匹配除了换行符之外的任意一个字符
    • \d 匹配一个数字
    • \s 匹配任意的空白字符,包括空格,制表符,换行符
    • \w匹配一个字母,包括字符,下划线,汉字等
    • ^ 匹配字符串的开头
    • $匹配字符串的结尾

    常见的用于重复的元字符

    • * 指定前面的内容(字符或者分组)可以重复任意多次,
    • + 指定前面的内容(字符或者分组)至少要重复1一次
    • ? 指定前面的内容(字符或者分组)重复0次或者1次
    • {n} 重复n次
    • {m,n} 重复至少m次,最多n次
    • {m,}重复至少m次,最多无穷次

    中括号[]

    匹配[]中的任意一个,单字符匹配

    []中没有元字符,所有的元字符在[]中都会失去意义,只有五个特殊字符^ - \ [ ].
    先详解一下这五个特殊字符的作用

    • 因为[ 和 ]本身和正则表达式[]冲突,所有如果要在[]中匹配[],需要对他们进行转义

    • 因为\是用来转义的,如果我们不对\转义,它就会对别人转义,所以如果要在[]中匹配\本身,我们需要使用\\

    • -[]中用来代表一个范围,比如[0-9],[a-z],当-挨着[或者]的时候,-表示它的字面意思,比如
      [-abc]会匹配-,a,b,c中的任意一个
      [a-c]会匹配a b c中的任意一个
      [a\-c]会匹配a,-,c这三个中的任意一个

    • ^只有在[]中的最开始才有特殊含义,表示排除,否则也是表示它的字面意思。比如
      [^0-9]匹配不包含0-9的任意字符。
      如果^[]中的其他位置,就会只表示它的字面意思了。

    比较常见的错误是[http|https],我们的本意是要匹配http或者https中的任意一个,但其实这个正则表达式和[ht|ps]是一模一样的,表示匹配h,t,p,|,s中的任意一个。

    要达到上面的效果,我们可以这样写(http|https),或者https?

    另外,当我们使用|的时候,一定要使用()进行限定,否则会出现各种各样奇葩的问题,因为|的匹配范围是从左到右,知道结束或者遇到)为止。

    分支条件|

    使用分支条件一定要使用()括起来,而且分支是短路的,只要符合其中的一个,就不会继续匹配分支中的其他条件了。

    反义,匹配不满足某个条件的字符串

    • \W 匹配任意不是字母,数字,下划线的字符
    • \S 匹配任意非空白字符
    • \D 匹配任意非数字的字符
    • \B 匹配任意的非单次开头或者结尾的位置
    • [^abc] 匹配不是a,b,c的任意字符

    分组()

    默认会给每一个分组一个分组号,从1开始分配,0代表整个正则表达式,我们可以在稍后通过分组号来引用前面的分组,比如\1代表引用第一个分组匹配到的内容,\n代表引用第n个分组匹配到的内容

    我们也可以给分组指定一个名称,在稍后可以通过这个名称来引用前面的分组,具体的做法是(?<name>expr),或者(?'name'expr),把这个分组的名字命名为name,在后面引用的时候可以\k<name>来进行引用。

    举几个例子加深印象。

    \b(\w+)\b\s+\1\b,可以匹配任意的重复单次,比如go go,good good等。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字\b(\w+)\b,这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符\s+,最后是分组1中捕获的内容(也就是前面匹配的那个单词)\1
    其中\1就是引用的第一个分组匹配到的内容。

    上面的例子也可以写成这样
    \b(?<name>w+)\b\s+\k<name>\b,这个表达式首先是一个单词,然后这个单次被捕获到了名字为name的分组中,在后来这个分组被引用了。

    我们也可以通过(?:expr)来将expr分组,但是不给它分配组号,这多用于我们确定不会在以后引用这个分组的内容的情况下。

    断言
    断言和\b,^,$一样,匹配一个位置,这个位置满足一定的条件。

    • 正预测断言
      (?=expr)断言一个位置,这个位置后面满足expr。比如\b\w+(?=ing\b),这个正则表达式匹配以ing结尾的单词的前半部分,比如dacing,会匹配到dac. 这个正则表达式的意思是,首先是一个单词,这个单次后面跟着ing

    • 正回顾断言
      (?<=expr)断言一个位置,这个位置前面满足expr,比如(?<=\bre)\w+\b,这个表达式的意思是,首先是一个单词,这个单次的前面是re,比如reading,会匹配到ading.

    • 负预测断言
      (?!expr)断言一个位置,这个位置后面不满足expr,。主要用去确保被匹配的字符串中不会出现一些字符,比如我们想要匹配这样一个字符串,它以hello开头,但是没有出现good,我们可以这样写
      \bhello.*(?!good)\w*\b

    • 负回顾断言
      (?<!expr)断言一个位置,这个位置前面不满足expr.比如(?<![a-z])\d{7},可以匹配不以小写字母开头的7位数字。

    可以看一下很实用的例子
    (?<=<(\w+)>).*(?=<\/\1>),这个可以用来匹配HTML标签中的内容,具体如下,首先是一个断言(?<=<(\w+)>),断言一个位置,这个位置前面是类似<body>这样的标签,然后是任意的字符,接下来又是一个断言(?=<\/\1>),断言这个位置后面是能匹配到前面那样的标签内容,只是多了一个反斜杠,比如<\body>

    贪婪域懒惰
    默认正则表达式是贪婪的,会尽可能多的匹配,比如字符串aabab,如果使用正则表达式a.*b去匹配的话,会匹配到整个字符串。
    有时候我们需要懒惰匹配,要尽可能少的匹配,这时候我们就需要在前面提到的用于重复的元字符后面加一个?,比如*?,+?,??,{n,m}?,{n,}?

    平常工作中能用到的正则表达式大概就是这些了。

    相关文章

      网友评论

          本文标题:正则表达式

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