常用正则表达式及基础知识

正则表达式

基础知识

  • 正则表达式具有特殊含义的标点符号

    ^ $ . * + ? = ! : | \ / ( ) [ ] { }

    想直接使用上面这些标点符号直接量,则必须使用前缀 \ 。

  • 正则表达式的字符类

    字符 匹配
    [...] 方括号内的任意字符
    [^...] 不在方括号内的任意字符
    . 除换行符和其他Unicode行终止符之外的任意字符
    \w 任何ASCⅡ字符组成的单词,等价于[a-zA-Z0-9]
    \W 任何不是ASCⅡ字符组成的单词,等价于[^a-zA-Z0-9]
    \s 任何Unicode空白符
    \S 任何非Unicode空白符的字符,注意\w和\S不同
    \d 任何ASCⅡ数字,等价于[0-9]
    \D 除了ASCⅡ数字之外的任何字符,等价于[^0-9]
    \b 退格直接量
  • 正则表达式的重复字符语法

    字符 含义
    {n,m} 匹配前一项至少n次,至多m次
    {n,} 匹配前一项n次或更多次
    {n} 匹配前一项n次
    匹配前一项0次或1次,也就是说前一项是可选的,等价于{0,1}
    + 匹配前一项1次或多次,等价于{1,}
    * 匹配前一项0次或多次,等价于{0,}
  • 正则表达式中的锚字符

    字符 含义
    ^ 匹配字符串的开头,在多行检索中,匹配一行的开头
    $ 匹配字符串的结尾,在多行检索中,匹配一行的结尾
    \b 匹配一个单词的边界,简言之,就是位于字符\w\W之间的位置,或位于字符\w和字符串的开头或者结尾之间的位置(但需要注意,[\b]匹配的是退格符)
    \B 匹配非单词边界的位置
    (?=p) 零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
    (?!p) 零宽负向先行断言,要求接下来的字符不与p匹配

    \b: 匹配的是单词,而不是单词中的某个部分。并且它只会匹配字符串开头结尾及空格回车等的位置,不会匹配空格符本身。

    比如在句子I like bike中,有很多的i,我只想匹配I这个独立的单词,那么需要使用\bI\b。注意\sI\s匹配的是I(单词前后有空格)。

    先行断言:如果在符号(?=之间加入一个表达式,他就是一个先行断言,用以说明圆括号内的表达式必须正确匹配,但不是真正意义上的匹配。比如,要匹配一种常用的程序设计语言的名字,但只在其后有冒号时才匹配,可以使用/[Jj]ava([Ss]cript)?(?=\:)/,这个正则表达式可以匹配"JavaScript: The Definitive Guide"中的"JavaScript",但是不能匹配"Java in a Nutshell" 中的"Java",因为它后面没有冒号。

  • 用于模式匹配的String方法(4种)

    search()replace()match()split()

  • 密码验证:包含大小写字母,数字,特殊字符

    以上类别都包含:/^(?=.?[a-z])(?=.?[A-Z])(?=.?\d)(?=.?[#@&.]).$/**

    如果是要求包含且只包含:/^(?=.?[a-z])(?=.?[A-Z])(?=.?\d)(?=.?[#@&.])[a-zA-Z\d#@&.]$/*

  • 正则提取字符

    假定我们正在检索的模式是一个或多个小写字母后面跟随了一位或多位数字,则可以使用模式/[a-z]+\d+/。但假定我们
    真正关心的是每个匹配尾部的数字,那么如果将模式的数字部分放到括号中(/[a-z]+(\d+)/),就可以从检索
    到的匹配中抽取数字了。

    var str='translate(12.5,32.1)';
    var _str=str.match(/translate\((.*)\)/);
     console.log(_str);
    
  • RegExp的方法

    • exec()

      exec()方法对一个指定的字符串执行一个正则表达式。就是在一个字符串中执行匹配检索,如果没有找到任何匹配,它就返回null,但如果它找到了一个匹配,它将返回一个数组。exec()方法与String方法match()相似,只是RegExp方法的参数是一个字符串,而String方法的参数是一个RegExp对象。

    • test()

      参数是一个字符串,用test()对某个字符串进行检测,如果包含正则表达式的一个匹配结果,则返回true。

使用案例

  • 后台传回来时间格式的字符串为2018-01-25 15:19:12.532,我们要转换成时间对象,本地使用Date.parse()去转换带有毫秒的字符串貌似会在ie内核浏览器上转换出错。

    不使用正则表达式:

    var str=`2018-01-25 15:19:12.532`;
    var objDate=Date.parse(str.replace(/-/g,'/').split('.')[0]);
    

    使用正则表达式:

    var str=`2018-01-25 15:19:12.532`;
    // \s表示任何的Unicode空白符,\S表示任何非Unicode空白符,[...]表示方括号内的任意字符,*表示匹配前一项0次或者多次
    var objDate=Date.parse(str.replace(/-/g,'/').replace(/\.[\s\S]*/g,'')); 
    
  • 特殊字符校验

    var regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im;
    var regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im;
    if (regEn.test(value) || regCn.test(value)) {
        alert('不能使用特殊字符');
        return false;
        }
    

常用表达式

  • 邮箱

    export const isEmail = (s) => {
        return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
    }
    
  • 手机号码

    export const isMobile = (s) => {
        return /^1[0-9]{10}$/.test(s)
    }
    
  • 电话号码

    export const isPhone = (s) => {
        return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
    }
    
  • 是否 url 地址

    export const isURL = (s) => {
        return /^http[s]?:\/\/.*/.test(s)
    }
    
  • 是否字符串

    export const isString = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'String'
    }
    
  • 是否数字

    export const isNumber = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Number'
    }
    
  • 是否 boolean

    export const isBoolean = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Boolean'
    }
    
  • 是否函数

    export const isFunction = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Function'
    }
    
  • 是否为 null

    export const isNull = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Null'
    }
    
  • 是否 undefined

    export const isUndefined = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Undefined'
    }
    
  • 是否对象

    export const isObj = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Object'
    }
    
  • 是否为数组

    export const isArray = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Array'
    }
    
  • 是否时间

    export const isDate = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Date'
    }
    
  • 是否正则

    export const isRegExp = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'RegExp'
    }
    
  • 是否错误对象

    export const isError = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Error'
    }
    
  • 是否Promise对象

    export const isPromise = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Promise'
    }
    
  • 是否Symbol函数

    export const isSymbol = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Symbol'
    }
    
  • 是否Set对象

    export const isSet = (o) => {
        return Object.prototype.toString.call(o).slice(8, -1) === 'Set'
    }
    
  • 严格的身份证校验

    export const isCardID = (sId) => {
        if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(sId)) {
            console.log('你输入的身份证长度或格式错误')
            return false
        }
        //身份证城市
        var aCity = { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外" };
        if (!aCity[parseInt(sId.substr(0, 2))]) {
            console.log('你的身份证地区非法')
            return false
        }
    
        // 出生日期验证
        var sBirthday = (sId.substr(6, 4) + "-" + Number(sId.substr(10, 2)) + "-" + Number(sId.substr(12, 2))).replace(/-/g, "/"),
            d = new Date(sBirthday)
        if (sBirthday != (d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate())) {
            console.log('身份证上的出生日期非法')
            return false
        }
    
        // 身份证号码校验
        var sum = 0,
            weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
            codes = "10X98765432"
        for (var i = 0; i < sId.length - 1; i++) {
            sum += sId[i] * weights[i];
        }
        var last = codes[sum % 11]; //计算出来的最后一位身份证号码
        if (sId[sId.length - 1] != last) {
            console.log('你输入的身份证号非法')
            return false
        }
    
        return true
    }
    
  • 检测密码强度

    export const checkPwd = (str) => {
        var Lv = 0;
        if (str.length < 6) {
            return Lv
        }
        if (/[0-9]/.test(str)) {
            Lv++
        }
        if (/[a-z]/.test(str)) {
            Lv++
        }
        if (/[A-Z]/.test(str)) {
            Lv++
        }
        if (/[\.|-|_]/.test(str)) {
            Lv++
        }
        return Lv;
    }
    

参考链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352