正则表达式

301 阅读6分钟

创建正则表达式对象

构造函数的方式创建(RegExp)

// 特殊符号需要转义
let reg = new RegExp("正则表达式")
// 特殊符号不需要转义
let reg = new RegExp(/正则表达式/)

字面量的方式创建(//)

let reg = /正则表达式/

相关函数

test(判断是否匹配成功)

// 判断字符串是否匹配,返回布尔值
/正则表达式/.test(字符串)

match(匹配单个或全部)

返回一个数组

// 匹配单个,返回第一个匹配到的
字符串.match(/正则表达式/)
// 加个g,表示全部匹配
// 字符串.matchAll(/正则表达式/)
字符串.match(/正则表达式/g)
// i: 忽略大小写,返回第一个匹配到的
字符串.match(/正则表达式/i)
// gi: 忽略大小写,并全部匹配
字符串.match(/正则表达式/gi)

matchAll(匹配全部)

返回一个数组

字符串.matchAll(/正则表达式/)

exec(匹配单个或全部)

返回一个数组

let str = "中国移动:10086,中国联通:10010,中国电信:10000"
let reg = /\d{5}/g
// 每次只输出一个
console.log(reg.exec(字符串))  // 10086(数组的形式)
console.log(reg.exec(字符串))  // 10010(数组的形式)
console.log(reg.exec(字符串))  // 10000(数组的形式)
console.log(reg.exec(字符串))  // null

replace(替换)

返回替换后的字符串

// 只替换匹配到的第一个
字符串.replace(/正则表达式/, 替换的内容)
// 替换匹配到的所有
字符串.replace(/正则表达式/g, 替换的内容)
// m: 表示匹配到的每一个
字符串.replace(/正则表达式/g, m => m.toLowerCase())

正则匹配规则

匹配单个字符

  1. . : 匹配任意一个字符,除\n(换行符)以外
  2. [] : 匹配[ ]中列举的字符
    ret = re.match("速度与激情[126789]", "速度与激情2")
    ret = re.match("速度与激情[1-35-9]", "速度与激情4")
    [.]: 表示一个点.([]:可以当作转义符来使用)
    
  3. [^] : 对里面列举的字符取反
    ret=re.match("速度与激情[^1a]", "速度与激情#")
    
  4. \d: 匹配数字, 即 0-9
  5. \D: 匹配非数字
  6. \s: 匹配空白,包含空格,tab键,回车(\r),换行(\n),\t
  7. \S: 匹配非空白
  8. \w: 匹配单词字符, 即字母、数字和下划线(0-9,a-z,A-Z,_)
  9. \W: 匹配非单词字符

匹配多个字符

  1. {m}: 匹配前一个字符出现m次
  2. {m,n}: 匹配前一个字符出现m到n次
  3. {m,}: 匹配前一个字符出现m次及其以上
  4. ? : 前一个字符出现1次或者0次
  5. *: 匹配前一个字符出现0次或者多次
  6. +: 匹配前一个字符出现1次或者多次

匹配开头与结尾

  1. ^ : 必须以xxx(正则表达式开头内容)为开头的字符串
  2. $ : 必须以xxx(正则表达式结尾内容)为结尾的字符串

匹配分组

  1. | : 逻辑或,匹配左右任意一个表达式

  2. () : 分组,也可以提升优先级

    // 分组1,2,3都是正则表达式的一部分
    字符串.match(/(分组1)(分组2)(分组3)/g)
    console.log(RegExp.$2) // 输出分组2匹配到的内容
    
    // 提升优先级,中间那个优先
    [0-9]|([a-z])|[A-Z]
    
  3. \num : 引用分组num匹配到的字符串

    示例:检验html网页语法的合法性(html双标签必须配对)

    // \1: 引用分组1匹配到的字符串
    ret = '<h1>dsafagd</h1>'.match(/<(\w+)>.*</\\1>/,)
    
  4. (?P<name>): 分组起别名

  5. (?P=name): 引用别名为name分组匹配到的字符串

    示例:检验html网页语法的合法性(html双标签必须配对)

    // 第一种方式
    ret = '<body><h1>dsafagd</h1></body>'.match(/<(\w+)><(\w+)>.*</\\2></\\1>/)
    // 第二种方式: 给分组取别名
    ret = '<body><h1>dsafagd</h1></body>'.match(/<(?P<p1>\w+)><(?P<p2>\w+)>.*</(?P=p2)></(?P=p1)>/)
    

贪婪和非贪婪

  1. Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),匹配尽可能多的字符;非贪婪则相反,匹配尽可能少的字符。(贪婪与非贪婪的前提是在满足整体匹配结果的情况下)
  2. 在"*","?","+","{m,n}" 量词后面加上?,使贪婪变成非贪婪
    *? : 0个
    +? : 1个
    ?? : 0个
    {m,n}? :m个
    

常用正则表达式

校验数字的表达式

  1. 数字: r"^\d*$"
  2. n位的数字: r"^\d{n}$"
  3. 至少n位的数字: r"^\d{n,}$"
  4. m-n位的数字: r"^\d{m,n}$"
  5. 零和非零开头的数字: r"^(0|[1-9][0-9]*)$"
  6. 非零开头的最多带两位小数的数字: r"^([1-9]\d*|[1-9]\d*.\d{1,2})$"
  7. 带1-2位小数的正数或负数: r"^(-)?\d+(.\d{1,2})?$"
  8. 正数、负数、和小数: r"^(-|+)?\d+(.\d+)?$"
  9. 有两位小数的正实数: r"^\d+(.[0-9]{2})$"
  10. 有1~3位小数的正实数: r"^[0-9]+(.[0-9]{1,3})$"
  11. 非零的正整数: r"^[1-9]\d*"r"([19][09])1,3" 或 r"^([1-9][0-9]*){1,3}" 或 r"^+?[1-9][0-9]*$"
  12. 非零的负整数: r"^-[1-9][0-9]*"r"[19]\d" 或 r"^-[1-9]\d*"
  13. 非负整数: r"^\d+"r"[19]\d0" 或 r"^[1-9]\d*|0"
  14. 非正整数: r"^-[1-9]\d*|0"r"((\d+)(0+))" 或 r"^((-\d+)|(0+))"
  15. 非负浮点数: r"^\d+"r"[19]\d\d˙0\d˙[19]\d0?0˙+0" 或 r"^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0"
  16. 非正浮点数: r"^((-\d+(.\d+)?)|(0+(.0+)?))"r"(([19]\d\d˙0\d˙[19]\d))0?0˙+0" 或 r"^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0"
  17. 正浮点数: r"^[1-9]\d*.\d*|0.\d*[1-9]\d*"r"(([09]+[˙09][19][09])([09][19][09][˙09]+)([09][19][09]))" 或 r"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))"
  18. 负浮点数: r"^-([1-9]\d*.\d*|0.\d*[1-9]\d*)"r"((([09]+[˙09][19][09])([09][19][09][˙09]+)([09][19][09])))" 或 r"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))"
  19. 浮点数: r"^(-?\d+)(.\d+)?"r"?([19]\d\d˙0\d˙[19]\d0?0˙+0)" 或 r"^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)"

校验字符的表达式

  1. 汉字: r"^[\u4e00-\u9fa5]{0,}$"
  2. 英文和数字: r"^[A-Za-z0-9]+"r"[AZaz09]4,40" 或 r"^[A-Za-z0-9]{4,40}"
  3. 长度为3-20的所有字符: r"^.{3,20}$"
  4. 由26个英文字母组成的字符串: r"^[A-Za-z]+$"
  5. 由26个大写英文字母组成的字符串: r"^[A-Z]+$"
  6. 由26个小写英文字母组成的字符串: r"^[a-z]+$"
  7. 由数字和26个英文字母组成的字符串: r"^[A-Za-z0-9]+$"
  8. 由数字、26个英文字母或者下划线组成的字符串: r"^\w+"r"\w3,20" 或 r"^\w{3,20}"
  9. 中文、英文、数字包括下划线: r"^[\u4E00-\u9FA5A-Za-z0-9_]+$"
  10. 中文、英文、数字但不包括下划线等符号: r"^[\u4E00-\u9FA5A-Za-z0-9]+"r"[4˘E009˘FA5AZaz09]2,20" 或 r"^[\u4E00-\u9FA5A-Za-z0-9]{2,20}"
  11. 可以输入含有^%&',;=?\"等字符: [^%&',;=?\x22]+
  12. 禁止输入含有的字符: [^]+

特殊需求表达式

  1. Email地址: r"^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$"
  2. 域名: r"[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?"
  3. InternetURL: r"[a-zA-z]+://[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$"
  4. 手机号码: r"^(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}$"
  5. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"): r"^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$"
  6. 国内电话号码(0511-4405222、021-87888822): "\d{3}-\d{8}|\d{4}-\d{7}"
  7. 身份证号(15位、18位数字): r"^\d{15}|\d{18}$"
  8. 短身份证号码(数字、字母x结尾): r"^([0-9]){7,18}(x|X)?"r"\d8,18[09x]8,18[09X]8,18?" 或 r"^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?"
  9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线): r"^[a-zA-Z][a-zA-Z0-9_]{4,15}$"
  10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线): r"^[a-zA-Z]\w{5,17}$"
  11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间): r"^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$"
  12. 日期格式: r"^\d{4}-\d{1,2}-\d{1,2}"
  13. 一年的12个月(01~09和1~12): r"^(0?[1-9]|1[0-2])$"
  14. 一个月的31天(01~09和1~31): r"^((0?[1-9])|((1|2)[0-9])|30|31)$"
  15. 钱的输入格式:
  16. 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000": r"^[1-9][0-9]*$"
  17. 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式: r"^(0|[1-9][0-9]*)$"
  18. 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号: r"^(0|-?[1-9][0-9]*)$"
  19. 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分: r"^[0-9]+(.[0-9]+)?$"
  20. 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的: r"^[0-9]+(.[0-9]{2})?$"
  21. 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样: r"^[0-9]+(.[0-9]{1,2})?$"
  22. 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样: r"^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$"
    1. 1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须: r"^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$"
  23. 备注: 这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉那个反斜杠,一般的错误都在这里
  24. xml文件: r"^([a-zA-Z]+-?)+[a-zA-Z0-9]+\.[x|X][m|M][l|L]$"
  25. 中文字符的正则表达式: "[\u4e00-\u9fa5]"
  26. 双字节字符: "[^\x00-\xff]" (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
  27. 空白行的正则表达式: "\n\s*\r" (可以用来删除空白行)
  28. HTML标记的正则表达式: r"<(\S*?)[^>]>.?</\1>|<.*? />" (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
  29. 首尾空白字符的正则表达式: r"^\s*|\s*"r"(\s)(\s"或 r"(^\s*)|(\s*)" (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
  30. 腾讯QQ号: r"[1-9][0-9]{4,}" (腾讯QQ号从10000开始)
  31. 中国邮政编码: r"[1-9]\d{5}(?!\d)" (中国邮政编码为6位数字)
  32. IP地址: r"\d+.\d+.\d+.\d+" (提取IP地址时有用)
  33. IP地址: r"((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))