zoukankan      html  css  js  c++  java
  • 正则表达式

    记录原因

    最近使用nodejs比较多,正则表达式对于匹配一个字符来说是比较重要的模块,但是自己本身对正则的概念也是过了一遍,在回头看正则表后就不认识了,所以我记录下正则的使用方法,并记录写经典的例子。

    什么是正则

    正则表达式是一组由字母和符号组成的特殊文本,它可以用来从文本中找出满足你想要的格式的句子。

    1.元字符

    元字符 描述
    . 句号匹配任意单个字符除了换行符
    [ ] 字符种类。匹配方括号内的任意字符。
    [^ ] 否定的字符种类。匹配除了方括号里的任意字符
    * 匹配>=0个重复的在*号之前的字符。
    + 匹配>=1个重复的+号前的字符。
    ? 标记?之前的字符为可选.
    {n,m} 匹配num个大括号之前的字符或字符集 (n <= num <= m).
    (xyz) 字符集,匹配与 xyz 完全相等的字符串.
    | 或运算符,匹配符号前或后的字符.
    转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ |
    ^ 从开始行开始匹配.
    $ 从末端开始匹配.

    1.1 .字符

    ".ar" => The car parked in the garage.
    .字符匹配任何单个字符。

    1.2 [ ]字符

    "[Tt]he" => The car parked in the garage.
    []方括叫字符集,里面放的参数加上拼的字符作为条件,里面的顺序不影响任何东西,例如,表达式[Tt]he 匹配 the 和 The。

    1.3 [^ ]否定字符集

    "[^c]ar" => The car parked in the garage.
    [^ ]上面的例子,就是除了c意外跟着ar的匹配方式

    1.4 重复次数

    后面跟着元字符 +,* or ? 的,用来指定匹配子模式的次数。 这些元字符在不同的情况下有着不同的意思。

    1.4.1 *号

    [a-z]* => The car parked in the garage#21.
    例子匹配所有小写的字符,*前的字符出现大于等于0次

    1.4.2 +号

    "c+t" => The fat cat sat on the mat.
    例子,是一个也不能匹配上,因为是+前字符出现大于等于1次,但是这里不能出现两个c,所以匹配不上。

    1.4.3 ?号

    "[T]?he" => The car is parked in the garage.
    例子,匹配到The和he,因为?是指前面的T出现一次或者零次。

    1.5 {}号

    "[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.
    上面的例子是[0-9]这些能匹配的数字,{2,3}指的是最少两个,最多三个字符的匹配。
    在正则表达式中 {} 是一个量词,常用来限定一个或一组字符可以重复出现的次数。

    1.6 (...) 特征标群和| 或运算符

    "(c|g|p)ar" => The car is parked in the garage.
    "(c|g|p)ar"指的是匹配car或gar或par这三个,()更像和数学中的()含义是一样的。
    "(T|t)he|car" => The car is parked in the garage.
    (T|t)he|car 匹配 (T|t)he 或 car
    或运算符就表示或,用作判断条件

    1.7 转码特殊字符

    "(f|c|m)at.?" => The fat cat sat on the mat.
    例子含义匹配fat.或fat或cat.或cat或mat.或mat
    用于指定 { } [ ] / + * . $ ^ | ? 这些特殊字符

    1.8 锚点

    在正则表达式中,想要匹配指定开头或结尾的字符串就要使用到锚点。^ 指定开头,$ 指定结尾。

    1.8.1 ^号

    "^(T|t)he" => The car is parked in the garage.
    ^是以The或the开头的数据,所以只能匹配到前面的The(指的是全部文档内容)。

    1.8.2 $号

    "(at.)$" => The fat cat. sat. on the mat.
    和^是相反的$,表示末尾是否能匹配上

    2.1 简写字符集

    正则表达式提供一些常用的字符集简写。如下:

    简写 描述
    . 除换行符外的所有字符
    w 匹配所有字母数字,等同于 [a-zA-Z0-9_]
    W 匹配所有非字母数字,即符号,等同于: [^w]
    d 匹配数字: [0-9]
    D 匹配非数字: [^d]
    s 匹配所有空格字符,等同于: [ f p{Z}]
    S 匹配所有非空格字符: [^s]
    f 匹配一个换页符
    匹配一个换行符
    匹配一个回车符
    匹配一个制表符
    v 匹配一个垂直制表符
    p 匹配 CR/LF(等同于 ),用来匹配 DOS 行终止符

    3.1 零宽度断言(前后预查)

    符号 描述
    ?= 正先行断言-存在
    ?! 负先行断言-排除
    ?<= 正后发断言-存在
    ?<! 负后发断言-排除

    先行断言和后发断言都属于非捕获簇(不捕获文本 ,也不针对组合计进行计数)。 先行断言用于判断所匹配的格式是否在另一个确定的格式之前,匹配结果不包含该确定格式(仅作为约束)。
    用人话说就是排除使用判断的内容,匹配剩余的内容,上面表格内容里的前后指的针对的字符串。
    例子:(?<=$)[0-9.]* =>$0,1,2,3,4,5,6,7,8,9,.

    3.1.1 ?=... 正先行断言

    ?=... 正先行断言,表示第一部分表达式之后必须跟着 ?=...定义的表达式。
    "(T|t)he(?=sfat)" => The fat cat sat on the mat.
    匹配到The。
    理解方式:匹配这个正先断言前的内容,包含不匹配断言。

    3.1.2 ?!... 负先行断言

    "(T|t)he(?!sfat)" => The fat cat sat on the mat.
    表达式 (T|t)he(?!sfat) 匹配 The 和 the,且其后不跟着 (空格)fat。
    理解方式:和正先断言相反,不匹配断言前的内容包含不匹配断言。

    3.1.2 ?<= ... 正后发断言

    "(?<=(T|t)hes)(fat|mat)" => The fat cat sat on the mat.
    表达式指的是the 或the 后跟fat或mat

    3.1.2 ?<= ... 负后发断言

    "(?<!(T|t)hes)(cat)" => The cat sat on cat.
    cat前跟的不是the 和The

    4.1 标志

    标志也叫模式修正符,因为它可以用来修改表达式的搜索结果。 这些标志可以任意的组合使用,它也是整个正则表达式的一部分。

    标志 描述
    i 忽略大小写。
    g 全局搜索。
    m 多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。

    4.1.1 忽略大小写 (Case Insensitive)

    "/The/gi" => The fat cat sat on the mat.

    "/.(at)/g" => The fat cat sat on the mat.

    4.1.3 多行修饰符 (Multiline)

    "/.at(.)?$/" => The fat
    cat sat
    on the mat.
    "/.at(.)?$/gm" => The fat
    cat sat
    on the mat.
    这个m会匹配每一行的结尾

    5.1 贪婪匹配与惰性匹配 (Greedy vs lazy matching)

    正则表达式默认采用贪婪匹配模式,在该模式下意味着会匹配尽可能长的子串。我们可以使用 ? 将贪婪匹配模式转化为惰性匹配模式。
    "/(.at)/" => The fat cat sat on the mat.
    "/(.
    ?at)/" => The fat cat sat on the mat.

    6.1 常见的正则分析

    6.1.1、数字、26个英文字母或者下划线组成的字符串:^w+$
    分析:^表示开头,w是字母数字缩写,+表示大于1个,$表示结束
    6.1.2、中文字符的正则表达式:[u4e00-u9fa5]
    6.1.3、^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])d{8}$
    分析:^(13是13开头,[0-9]零到九,14[5|7]:14开头,5或7,15[0|1|2|3|5|6|7|8|9],18[0|1|2|3|5|6|7|8|9]和前面一样,d{8}匹配数字,至少8位
    6.1.4、身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(d{15}$)|(d{18}$)|(^d{17}(d|X|x)$)
    分析:d{15}$是最少15数字,|(d{18}$)或者18位数字,(^d{17}(d|X|x)$)或者17位数字加上大小x
    6.1.5、Email地址:^w+([-+.]w+)@w+([-.]w+).w+([-.]w+)$
    分析:^w+是开头随机数大于一个,([-+.]w+)
    多个-或随机一个加上数字多个,这个组个是大于零的,@w+([-.]w+)是@加上数子-或者任何数在机上数字,.w+([-.]w+)$是和前那一样
    6.1.6、日期格式:^d{4}-d{1,2}-d{1,2}
    6.1.7、匹配括号外所有的逗号,理解了好久
    ,+(?=[^)]*((|$))
    匹配方式是逗号有大于等于一个,贪婪正向断言,除去,),但是有*所以匹配一个多个,,所有的逗号都能匹配上,加上后面的(|$之前的贪婪匹配方式,就可以获取到所有括号外的逗号。
    6.1.8、获取文件名称:

    let csvFileName = fileName.match(new RegExp('(?<=(?!.*/)).*(?=(.csv)$)', 'g'));
    

    这里是全局匹配,以.csv为结束,加上正先断言,中间使用.*匹配所有字符,这个前面是?!负先断言,而且是非贪婪匹配所以加上/就匹配到最后那个/
    之后,我发现能简写成

    let csvFileName = fileName.match(new RegExp('(?!.*/).*(?=(.csv)$)', 'g'));
    

    感谢

  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/liuyang95/p/14165799.html
Copyright © 2011-2022 走看看