JavaScript正则表达式

(1) 认识正则表达式
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法,,计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。”
(2) 快速入门案例
需求:验证用户的账号必须是158/188开头手机号码
① 原始验证

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div>
    <label for="username">账号:</label>
    <input type="text" name="username" id="username">
    <p id="result">等待验证结果</p>
  </div>
  <script>
    function $(selector) {
      return document.querySelector(selector)
    }
    // 获取需要的标签
    var _input = $("#username") // 用户输入的账号
    var _result = $("#result")  // 展示验证结果
    _input.onkeyup = function () {
      // 声明了变量,默认是合法账号
      var flag = true
      // 账号长度 11位
      // 158/188开头
      // 每一位都是数字
      var _value = _input.value // 获取用户输入的数据
      // 验证长度
      if (_value.length === 11) {
        // 验证158/188开头
        if (_value.startsWith("158") || _value.startsWith("188")) {
          // 验证数字
          for (var i = 0; i < _value.length; i++) {
            if (_value.charCodeAt(i) >= 48 && _value.charCodeAt(i) <= 57) {
              flag = true
            } else {
              console.log("账号中包含了非法字符")
              // _result.innerText = "账号中包含了非法字符"
              flag = false
              break
            }
          }
        } else{
          // _result.innerText = "账号不是158/188开头"
          flag = false
        }
      } else {
        // _result.innerText = "账号长度不合法"
        flag = false
      }
      // 展示结果
      if(flag) {
        _result.innerText = "账号合法,可用"
      } else {
        _result.innerText = "账号不合法,长度11位、158|188开头"
      }
    }
  </script>
</body>
</html>

② 正则验证

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div>
    <label for="username">账号:</label>
    <input type="text" name="username" id="username">
    <p id="result">等待验证结果</p>
  </div>
  <script>
    function $(selector) {
      return document.querySelector(selector)
    }
    // 获取需要的标签
    var _input = $("#username") // 用户输入的账号
    var _result = $("#result")  // 展示验证结果
    _input.onkeyup = function () {
      // 声明一个正则表达式
      var reg = /^(158|188)\d{8}$/ig
      // 验证账号
      if(reg.test(_input.value)) {
        _result.innerText = "账号合法,可用"
      } else {
        _result.innerText = "账号11位、158|188开头."
      }
    }
  </script>
</body>
</html>

(3) 正则表达式语法
① 正则表达式声明
JavaScript中正则表示的声明方式有两种:

// 创建一个正则表达式对象
var reg = /hello/      // 创建了一个匹配hello单词的正则表达式【推荐】
// 创建一个正则表达式对象
var reg = new RegExp("hello") // 创建了一个匹配hello单词的正则表达式

操作正则表达式的修饰符:

修饰符 描述
i ignorecase 忽略大小写的意思
g global全局匹配的意思,对目标字符串进行全部测试
m multiple rows多行匹配
// 创建一个正则表达式对象
var reg = /hello/i      // 创建了一个匹配hello单词的正则表达式,忽略大小写
// 创建一个正则表达式对象
var reg = new RegExp("hello", "i") // 创建了一个匹配hello单词的正则表达式

② 常见描述符号
a. 任意单个字符匹配、字符串开头、字符串结尾匹配

符号 描述
. 表示匹配任意单个字符
^ 表示匹配字符串开头位置
$ 表示匹配字符串结束位置
// 符号:
// . :匹配任意一个字符
// ^ :匹配字符串开头位置
// $ :匹配字符串结束位置
var url = "http://www.baidu.com"
var reg = /^http/i // 测试目标字符串是否以http开头
console.log( reg.test(url) )
var email = "damu@aliyun.com"
var reg2 = /@aliyun.com$/ig // 测试目标字符串是否@aliyun.com结尾
console.log( reg2.test(email) )
var intro = "helloworld"
var reg3 = /wo/ig   // 判断目标字符串中是否包含wo
console.log( reg3.test(intro) )

b. 匹配任意单个数字、小写字母、大写字母

符号 描述
[0-9] 匹配任意一个0~9的数字
\d 匹配任意一个0~9的数字,等价于[0-9]
[a-z] 匹配任意一个小写字母
[A-Z] 匹配任意一个大写字母
[a-zA-Z] 匹配任意一个字母
[a-zA-Z0-9_] 匹配任意一个数字、字母或者下划线
\w 匹配任意一个数字、字母或者下划线
[abc] 匹配任意一个字母a或者b或者c
\D 匹配任意一个非数字字符
\W 匹配任意一个非数字/字母/下划线的字符
// 匹配字符、数字、下划线
// [0-9]、\d:表示匹配任意单个数字
// [a-z]:表示匹配任意单个小写字母
// [A-Z]:表示匹配任意单个大写字母
// [a-zA-Z0-9_]、\w:表示匹配任意单个数字、下划线、字母
var strNo = "0abc"
var r1 = /^[0-9]/ig // 判断是否以数字开头
console.log( r1.test(strNo) )   // true
var name = "tom"
var r2 = /^[a-z]/    // 判断是否以(单个)小写字母开头
var r3 = /^[A-Z]/    // 判断是否以(单个)大写字母开头
console.log( r2.test(name) )  // true
console.log( r3.test(name) )  // false
var username = "_admin"
var r4 = /^\w/ // 判断是否以 下划线/数字/字母 开头
console.log( r4.test(username) )
var str = "administrator"
var r5 = /^[abc]/  // 判断是否a或者b或者c开头
console.log( r5.test(str) )

c. 正则表达式中的量词

符号 描述
x* 表示前面的字符x出现了0次或者多次
x? 表示前面的字符x出现了0次或者1次
x+ 表示前面的字符x出现了1次或者多次
x{m,n} 表示前面的字符x出现了至少m次最多n次
x{m,} 表示前面的字符x出现了至少m次
x{,n} 表示前面的字符x之多出现了n次
x{m} 表示前面的字符x出现了m次
// 量词测试:某个字符出现的次数(量词)
// *
// ?
// +
// {}
var str = "hello world"

var r1 = /x*/   // 测试字符串中x出现了0次或者多次
console.log(r1.test(str)) // true

var r2 = /e?/  // 测试字符串中e出现了0次或者1次
console.log(r2.test(str)) // true

var r3 = /x+/  // 测试字符串中x出现了1次或者多次
console.log(r3.test(str))  // false

var r4 = /l{3,5}/ // 测试字符l连续出现了至少3次最多5次
console.log(r4.test(str))  //false

var r5 = /l{2,}/ // 测试字符l连续出现了至少2次以上
console.log(r5.test(str))

var r6 = /l{,3}/  // 测试字符l连续出现了最多3次
console.log(r6.test(str))  // false ?思考,这里为什么是false

var r7 = /l{3}/  // 测试字符l是否连续出现了3次
console.log(r7.test(str))

d. 正则表达式中的分组,使用圆括号|小括号,将一段字符作为一个整体进行匹配

符号 描述
(abc) 表示匹配字符串中是否出现了abc字符
(com/cn) 表示匹配字符串中是否出现了com或者cn字符串

e. 正则表达式中的转义符号:字符串中可能出现了特殊符号

符号 描述
\ 转义符号
\[ 匹配一个字符[
// 转义符号
var fav = "['篮球', '游戏', '音乐']"
var reg = /^\[/    // 测试字符串是否以[符号开头
// \[:表示[符号只是一个普通字符,不是正则表达式中的特殊符号
console.log(reg.test(fav))

(4) 正则表达式扩展
字符串的操作函数match() / search() / replace()也可以使用正则表达式进行替换

var s = "he22llo55 wor66ld99"
s.replace(/\d+/, "**") // "he**llo** wor**ld**"

字符串替换:贪婪模式、懒惰模式(非贪婪模式):

  • 贪婪模式:正则表示尽可能多的匹配目标数据
  • 懒惰模式(非贪婪模式):尽可能精确的匹配目标数据
// 原始数据
var s = "<div> <p>1111</p> <div>内容</div> <p>222</p> </div>"
// 1、贪婪模式:尽可能多的匹配数据
var r1 = /^<div>.*<\/div>/ig
s.match(r1) // "<div> <p>1111</p> <div>内容</div> <p>222</p> </div>"
// 2、非贪婪模式:也称为懒惰模式,尽可能精确的匹配数据
var r2 = /^<div>.*?<\/div>/ig
s.match(r2) // "<div> <p>1111</p> <div>内容</div>"
// 结论:任意正则表达式语句,匹配数据时添加上?结尾,都会从贪婪模式转换为非贪婪模式

(5) 扩展案例
使用正则表达式,处理密码强度等级

  • 如果密码只使用了数字或者字母或者特殊符号,定义:弱
  • 如果密码只使用了数字或者字母或者特殊符号里面的两种,定义:较强
  • 如果密码只使用了数字或者字母或者特殊符号里面三种,定义:强


    image.png
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    #strong{
      margin: 10px;
      display: flex;
    }
    #strong span{
      display: inline-block;
      margin-right:5px;
      border-radius: 5px;
      width:50px;
      height:10px;
      border:solid 1px #000;
    }
  </style>
</head>
<body>
  <div>
    <label for="password">密码:
      <input type="text" name="password" id="password">
      <div id="strong">
        <span></span>
        <span></span>
        <span></span>
        <p></p>
      </div>
    </label>
  </div>

  <script>
    function $(selector) {
      return document.querySelectorAll(selector)
    }
    // 获取密码输入框
    var _password = $("#password")[0]
    // 获取span
    var _spans = $("span")
    var _p = $("p")[0]
    _password.onkeyup = function() {
      // 每次输入时,清空强度显示
      for(var i = 0; i < _spans.length; i++) {
        _spans[i].style.background = "white"
      }
      // 获取密码
      var _passVal = _password.value
      // 判断强度等级:count:默认0 1-弱  2-较强 3-强
      var count = 0 
      if(/[a-zA-Z]/.test(_passVal)) {
        count++
      }
      if(/\d/.test(_passVal)) {
        count++
      }
      if(/\W/.test(_passVal)) {
        count++
      }
      // 设置密码强度
      for(var i = 0; i < count; i++) {
        var bg = "white"
        switch(count) {
          case 1:
            bg = "red";
            _p.innerText = "弱密码"
            break;
          case 2:
            bg = "orange"
            _p.innerText = "较强密码"
            break;
          case 3:
            _p.innerText = "强密码"
            bg = "green"
        }
        _spans[i].style.background = bg
        _p.style.color = bg
      }
    }
  </script>
</body>
</html>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容