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'));
    

    感谢

  • 相关阅读:
    Python中os与sys两模块的区别
    单线程爬取图片
    linux下glances服务器监控工具
    python中的join()函数的用法
    python的exec、eval详解
    mongodb启动不了解决方法
    生产者和消费者(.net实现)
    IOS开发--第一阶段--导行(1)(基本概念)
    12.26 linux基本操作指令
    12.25
  • 原文地址:https://www.cnblogs.com/liuyang95/p/14165799.html
Copyright © 2011-2022 走看看