最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 正则表达式细讲

    正文概述 掘金(爱上码代码农民)   2021-08-04   507

    概念

    正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式(规则),是由普通字符(比如a-z字母)和特殊字符(也称元字符)组成

    正则表达式用途

    • 【检索】匹配数据格式(比如,登录、注册时的格式校验)
    • 【替换】替换文本内容(比如,对一些非法字符的替换等)
    • 【提取】从字符串中提取我们要的特定部分(比如,截取URL域名或者参数)

    RegExp语法

    • 通过构造函数的方式创建正则表达式对象:const reg = new RegExp("pattern", modifiers) 一般会用在正则匹配主体不确定的情况下使用
    • 利用字面量创建正则表达式对象:const reg = /pattern/modifiers这种写法比较常用

    RegExp的对象方法

    • compile:编译正则表达式 1.5版本已废除
    • exec:检索字符串中指定的值,返回找到的值,确定其位置
    • test:检索字符串中是否存在指定的值,返回true或false
    • toString:返回正则表达式的字符串

    RegExp对象方法使用姿势

    test 这个是比较常用的方法,判断是否符合匹配模式的都可以用这个方法,比如表单格式校验、是否包含指定非法字符等

    比如

    # 如果是全局匹配的话,会在每次匹配完更改lastIndex值
    var reg = /lucky/g
    reg.test('I am lucky boy') // 返回true
    
    # lastIndex变化例子
    var a = /ab/g
    var str = 'kkabkkabkk'
    a.test(str) // 此时匹配到的是第一个ab,返回true
    a.lastIndex  // 4
    a.test(str) // 此时匹配到的是第二个ab,返回true
    a.lastIndex // 8
    a.test(str) // 此时lastIndex为8,往后已经匹配不到了,返回false
    a.lastIndex // 0,被重置为初始值
    a.test(str) // 此时又开始从头开始匹配,返回0
    

    exec 检索字符串中的指定值,返回的是被找到的值(一个数组),如果没有匹配到,则返回null

    const reg = /chen/
    reg.exec('My name is chenjiaobin') 
    # return ["chen", index: 11, input: "My name is chenjiaobin", groups: undefined]
    
    1. 元素0 表示与正则表达式相匹配的文本
    2. 元素1 表示与第一个子表达式reg = /(partten)/相匹配的文本,如果有多个,以此类推,元素3、4...
    // 两个子表达式的正则,最后返回的结果的下标1和下标2的值分别对应子表达式匹配到的值
    const reg = /(chen)(jiao)/
    reg.exec('My name is chenjiaobin')
    
    // 返回 ["chenjiao", "chen", "jiao", index: 11, input: "My name is chenjiaobin", groups: undefined]
    
    
    1. index元素则是匹配文本的第一个字符的位置
    2. input匹配的则是被检索的字符串
    3. group是用来存储命名捕获组的信息,只有捕获组使用命名的时候才会有值,比如,
    # ?<first>就是为捕获组设置别名
    const reg = /(?<first>chen)/
    reg.exec('My name is chenjiaobin')
    
    # return ["chen", "chen", index: 11, input: "My name is chenjiaobin", groups: { first: 'chen' }]
    
    1. 当设置正则表达式为全局的时候,会在RegExp的lastIndex属性指定的字符开始检索字符串,

    当匹配到对应文本后,RegExp的lastIndex属性会重新被设置为匹配文本的最后一个字符的下一个位置下标,直到被匹配文本没有可以被匹配的文本,返回null,且lastindex被重置为0,因此,当我们需要反复使用同一个正则表达式的时候,在匹配新的字符串之前重置lastIndex为0;或者不把实例化好的正则实例赋值给变量,而是直接使用/partern/.exec('abcd')

    var reg = /a/g
    reg.exec('abcdabcdabcd') # 第一次 return ["a", index: 0, input: "abcdabcdabcd", groups: undefined]
    reg.exec('abcdabcdabcd') # 第二次 return ["a", index: 4, input: "abcdabcdabcd", groups: undefined]
    reg.exec('abcdabcdabcd') # 第三次 return ["a", index: 8, input: "abcdabcdabcd", groups: undefined]
    reg.exec('abcdabcdabcd') # 第四次 return null
    
    # 没有全局修饰符g
    var reg = /a/
    reg.exec('abcdabcdabcd') # 始终返回 ["a", index: 0, input: "abcdabcdabcd", groups: undefined]
    
    # exec如果不是全局模式的话,跟match返回的是一样的
    # match如果是全局模式的话,会一次性返回结果,比如 
    'abcdabcdabcd'.match(/a/g) // return ['a', 'a', 'a']
    

    支持正则表达式的String对象的方法

    • search:检索与正则表达式匹配的值
    • match:找到一个或多个正则表达式的匹配
    • replace:替换与正则表达式匹配的字符串(不改变原始字符串)
    • split:分割字符串为字符串数组(不改变原始字符串)

    String对象方法使用姿势

    search

    string.search(searchValue)
    # searchValue可以是字符串或者是正则表达式,如果匹配的上就返回第一个的下标,否则返回-1
    

    match

    该方法的行为很大程度依赖于是否是全局模式,匹配不到返回null

    # 非全局,只匹配了一次,返回的结果跟exec一样
    var reg = /chen/
    'chenjiaochen'.match(reg)
    # 返回 ["chen", index: 0, input: "chenjiaochen", groups: undefined]
    
    # 全局
    var reg = /chen/g
    'chenjiaochen'.match(reg)
    # 返回 ["chen", "chen"]
    

    replace

    string.replace(separator, str|fn)
    // 第二个参数可以是字符串或者是匿名函数,匿名可以让我们对匹配到的字符串为所欲为的改动,比如
    
    const str = '他今年22岁,她今年20岁,他的父亲今年40岁,她的父亲今年45岁,总共有4个人'
    const reg = /(\d+)岁/g
    // 第一个参数表示匹配到的字符,第二个参数表示匹配时的字符最小索引位置(RegExp.index),第三个参数表示被匹配的字符串(RegExp.input),实际上参数的个数是不确定的,会随着子匹配的变多而变多
    function formatAge (a, b, d) {
        const year = (new Date()).getFullYear()-parseInt(a)-1
        return a + '(' + year + '年出生)'
    }
    str.replace(reg, formatAge)
    // return "他今年22岁(1998年出生),她今年20岁(2000年出生),他的父亲今年40岁(1980年出生),她的父亲今年45岁(1975年出生),总共有4个人"
    
    var regex = /(\d{4})-(\d{2})-(\d{2})/;
    var string = "2017-06-12";
    var result = string.replace(regex, function(match, year, month, day) {
    	return month + "/" + day + "/" + year;
    });
    console.log(result); 
    // => "06/12/2017"
    

    split

    string.split(separator, limit)
    # 第一个参数为指定分割符,可以是字符串或正则表达式,第二个参数指定返回的数组的最大长度
    

    修饰符

    修饰符含义描述
    iignore-不区分大小写设置匹配字符不区分大小写,A和a没区别gglobal-全局匹配查找所有匹配项(注:使用的时候要注意lastIndex是否被重置的问题)mmultiline-多行匹配使边界字符^和$匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾s特殊字符原点(.)中包含换行字符 \n默认情况下圆点匹配换行字符\n之外的任何字符,加上s修饰符后,则(.)中包含换行符 \n

    m 多行匹配例子:

    const str = 'abc\nabc\nabc'
    str.match(/^abc/g) // return ['abc'] 只返回了一个匹配值,因为其他两个都换行了
    str.match(/^abc/gm) // return ['abc', 'abc', 'abc'] 修饰符添加了个多行匹配
    

    s 修饰符例子:

    const str = 'bei\nzuo\nsi'
    str.match(/bei./) // return null 没有匹配到任何数据,返回了null
    str.match(/bei./s) // return ['bei', ......] 匹配到了一个字符串,返回了一个数组
    

    元字符(常用)

    字符描述
    \将下一字符标记为一个特殊字符或原意字符,比如\n表示一个换行字符^匹配输入字符串的开始位置,如果设置了multiline属性,^ 也匹配\n或\r之后的位置,如'abc\nab'.match(/^ab/gm)',返回['ab','ab'],如果没有m则返回['ab']$匹配字符串的末尾,如果设置了multiline属性,$也匹配\n或\r之前的位置*匹配前面的子表达式0次或多次,如zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}+匹配前面的指标是是一次或多次,如'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}?匹配前面的子表达式0次或1次,如"do(es)?" 可以匹配 "do" 或 "does" 。? 等价于 {0,1}{n}n是一个非负整数,匹配确定的n次,如'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o{n,}匹配至少n次,如'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'[xyz]字符集合,匹配所包含的任意字符,[up]可以匹配lucky中的u[^xyz]跟[xyz]相反,匹配未包含集合的任意字符,如[up]可以匹配lucky中的l c k y[a-z]匹配字符范围,匹配指定范围内的任意字符,当然也可以[a-c]这种[^a-z]跟[a-z]相反\b匹配单词边界,也就是单词和空格间的位置,如er\b可以匹配nerver中的er,也可以匹配'aer b'的er,不能匹配verb中的er\B匹配非单词边界,'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'\d(\D相反)匹配一个数字字符,等价于[0-9]\s(\S相反)匹配任何空白字符,包括空格、制表符、换页符等,等价于[\f\n\r\t\v]\w(\W相反)匹配字母、数字、下划线,等价于[A-Za-z0-9_](pattern)分组捕获,匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 00…0…9 属性。要匹配圆括号字符,请使用 '(' 或 ')'。.匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括\n在内的任何字符,可以使用`.

    拓展解释

    1. ?:如果该字符跟在其他限制符( *, +, ?, {n}, {n,}, {n,m} )后面时,匹配模式是非贪婪的,即会尽可能少的匹配所搜索的字符串,而默认的贪婪模式则时尽可能多的匹配内容,如ooo,'o+?'只会匹配单个'o',而'o+'将匹配所有'o'
    2. 对一些特殊字符($、()、*、+、. 、[、? 、\、^、{ 、|),如果要匹配他们需要在他们前面添加转义符 \n
    3. + 和 *都是贪婪的,它们会可能多的匹配文字,我们可以通过在他们后面加上一个 ? 就能实现非贪婪或最小匹配。比如:匹配 我滴个神哦,正则为/<.*>/,那么匹配出来的是整个字符串,如果正则为/<.*?>/,那么匹配出来的就只是前面的
    4. 圆括号( )表示捕获分组,它会把分组里匹配的值保存起来。我们可以利用这个临时缓存,通过\n的方式表示特定匹配内容,比如/([a-z]+)abc\1/这样通过\1来代替再一次写([a-z]+)这一个规则。但用圆括号会有一个副作用,会使相关的匹配被缓存,此时可以用 ?: 放在第一个选项前来消除这种副作用。
    var reg = /(chen)jiaobin(kevin)/
    'chenjiaobinkevinkk'.replace(reg, '$1测试$2')
    # 返回:chen测试kevinkk($1获取到的是chen,$2获取到的是kevin)
    
    
    # 使用?:消除圆括号带来的缓存
    var reg = /(?:chen)jiaobin(kevin)/
    'chenjiaobinkevinkk'.replace(reg, '$1测试$2')
    # 返回:kevin测试$2kk
    # 因为第一个圆括号的缓存被消除了,所以$1获取到的是kevin,$2获取不到被当成字符串输出
    # 如果要$1和$2都失效那么就都在前面添加?:符号
    # 加了?:符号后替换符号\1等也失效
    
    
    'chenjiaobinchenkk'.match(/(chen)jiaobin\1/)
    # 返回 ["chenjiaobinchen", "chen", index: 0, input: "chenjiaobinchenkk", groups: undefined]
    # 此时匹配中的\1代表的是chen这个字符串,整个正则同等`/(chen)jiaobinchen/`
    
    'chenjiaobinchenkk'.match(/(?:chen)jiaobin\1/)
    # 返回的是null,此时被消除了缓存,\1表示的就是自己
    
      • exp1(?=exp2):查找exp2前面的exp1 (比如'ageoldageyear'.match(/age(?=year)/,匹配到的是后面的)
      • (?<=exp2)exp1:查找exp2后面的exp1
      • exp1(?!exp2):查找后面不是exp2的exp1
      • (?<!exp2)exp1:查找前面不是exp2的exp1

    运算符优先级

    以下优先级上到下是高到低排序

    \ :转义符
     () (?:) (?=) [] :圆括号和方括号
    *, +, ?, {n}, {n,}, {n,m}: 限定符
    ^, $, \任何元字符、任何字符 : 定位点
    | :或操作
    

    优先级问题一般比较少见,不过还是需要了解下,比如 m|food 会匹配出m或者food,而不是mood或food,因为字符的比较优先级大于”或“操作,可以这样改(m|f)ood就没问题了

    常用正则场景匹配规则

    汉字:^[\u4e00-\u9fa5]{0,}$
    身份证(15或18或17+校验位X x):(^\d{15})|(^\d{18})|(^\d{17}(\d|X|x)$)
    邮箱校验:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
    手机号码:^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$
    

    正则校验查看器

    • Regulex:jex.im/regulex/#!f… (推荐)
    • 菜鸟工具:c.runoob.com/front-end/8…

    正则相关文章

    • 菜鸟教程:www.runoob.com/regexp/rege…
    • CSDN文章:blog.csdn.net/whitegay/ar…
    • RegExp对象和支持正则的String方法:www.runoob.com/jsref/jsref…
    • 掘金(老姚):juejin.cn/post/684490…
    • 正则表达式电子书下载

    起源地下载网 » 正则表达式细讲

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元