day14JS-正则表达式

news2024/9/28 9:24:18

1. 什么是正则表达式

  • 正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),可以用来描述和匹配字符串的特定模式
  • 正则表达式是一种用于模式匹配和搜索文本的工具
  • 正则表达式提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。
  • 正则表达式可以应用于各种编程语言和文本处理工具中,如 JavaScript、Python、Java、Perl 等。

2. 正则表达式的声明(创建)方式

2.1 字面量声明(创建)

字面量创建是最简便的方式.。

声明(创建)语法: var/let 变量名 = /文本内容/修饰符;

let reg = /a/g;

2.2 实例化声明(创建)

声明(创建)语法:var/let 变量名= new RegExp("文本内容","修饰符");

let reg1=new RegExp("a","g")

 3.正则表达式的修饰符

正则表达式是只匹配一个字符

  1. g : 全局搜索。
  2. i :不区分大小写搜索。
  3. m :多行搜索。
  4. s : 允许 . 匹配换行符。
  5. u : 使用 unicode 码的模式进行匹配。
  6. y : 执行“粘性 (sticky)”搜索,匹配从目标字符串的当前位置开始。

修饰符可以多个一起使用。

replace()是替换方法。

 案例:

var str="abAc";
//这里的replace是普通的字符串方法
str=str.replace("a","0");
console.log(str);//0bAc

//这里是使用了正则表达式,查找字符串中有没有字符a,有则替换成字符0,只替换一个
str=str.replace(/a/,"0");
console.log(str);//0bAc

//这里是使用了正则表达式,查找字符串中所有的字符a,有则替换成字符0,全局替换
str=str.replace(/a/g,"0");
console.log(str);//0bAc

//这里是使用了正则表达式,查找字符串中所有的字符a,有则替换成字符0,全局替换并且不区分大小写
str=str.replace(/a/gi,"0");
console.log(str);//0b0c

4. 正则表达式的API(属性+方法)

4.1 正则表达式相关的属性

  1. flags :获取正则表达式使用到的修饰符。返回值是修饰符。
  2. source :获取到正则的内容。返回值是文本内容。
  3. lastIndex :获取最后一次查找的下标。返回值是索引下标。
  4. unicode :获取正则表达式是否使用的编码。返回值是true或false。
  5. global :正则表达式是否使用了修饰符g。返回值是true或false。
  6. ignoreCase :正则表达式是否使用了修饰符i。返回值是true或false。
  7. multiline :正则表达式是否使用了修饰符m。返回值是true或false。
  8. dotAll :正则表达式是否使用了修饰符s。返回值是true或false。
  9. sticky :正则表达式是否使用了修饰符y。返回值是true或false。

案例:

var reg = /a/gim;
console.log(reg.flags);//修饰符
console.log(reg.source);//正则内容
console.log(reg.global);//g
console.log(reg.ignoreCase);//i
console.log(reg.lastIndex);//最后一次查找的下标
console.log(reg.dotAll);
console.log(reg.multiline);//m
console.log(reg.sticky);//粘性
console.log(reg.unicode);//编码


-----------------------------------------
答案:
var reg = /a/gim;
console.log(reg.flags);//"gim"
console.log(reg.source);//"a"
console.log(reg.global);//true
console.log(reg.ignoreCase);//true
console.log(reg.lastIndex);//最后一次查找的下标0
console.log(reg.dotAll);//false
console.log(reg.multiline);//true
console.log(reg.sticky);//false
console.log(reg.unicode);//false

4.2 修饰符与正则属性的对应关系

标志描述对应属性
d生成子串匹配的索引。hasIndices
g全局查找。global
i忽略大小写查找。ignoreCase
m允许 ^ 和 $ 匹配换行符。multiline
s允许 . 匹配换行符。dotAll
u“Unicode”;将模式视为 Unicode 码位序列。unicode
v升级 u 模式,提供更多 Unicode 码特性。unicodeSets
y执行“粘性(sticky)”搜索,从目标字符串的当前位置开始匹配。sticky

4.3 正则的元字符

元字符(Metacharacter)是拥有特殊含义的字符。

  1. . :查找单个字符,除了换行和行结束符。
  2. \w :查找数字、字母及下划线
  3. \W :查找非英文单词字符
  4. \d :查找数字
  5. \D:查找非数字字符
  6. \s:查找空白字符
  7. \S:查找非空白字符
  8. \b:匹配单词边界。
  9. \B:匹配非单词边界。
  10. \0 :查找 NULL 字符
  11. \n : 查找换行符
  12. \f :查找换页符
  13. \r:查找回车符
  14. \t :查找制表符
  15. \v :查找垂直制表符
  16. \xxx:查找以八进制数 xxx 规定的字符。
  17. \xdd:查找以十六进制数 dd 规定的字符。
  18. \uxxxx:查找以十六进制数 xxxx 规定的 Unicode 字符。
  1. . 通配符元字符:表示匹配任意一个字符
  2. \ : 转移符号。
  3. [ 字符串 ] :表示匹配[ ]内任意一个字符。 虽然在[ ]中部分具有一定含义的字符会转义,但是建议大家还是用\转义。
  4. [.] :代表字符. 不再是任意字符

案例1:

    // 正则的元字符
    var str="abcacdade";
    var reg=/ac/g;
    // . 通配符元字符 代表任意一个字符
    var reg=/a../g;
    console.log(reg.exec(str));
    console.log(reg.exec(str));
    console.log(reg.exec(str));

案例2:

    var str="abacad";
    console.log(str.match(/a[bd]/g));
    console.log(str.match(/[ab][cd]/g));//ac ad bc bd

4.4 正则表达式相关的方法

4.4.1 正则表达式自身的方法

test()判断当前字符串中是否有满足该正则匹配的内容返回值是布尔值

exec():在字符串中查找满足正则匹配的内容返回值是数组,数组有对应的属性。

案例: 

var reg = /a/gim;

console.log(reg.test("aa"));

console.log(reg.exec("aa"));

test()方法使用全局匹配时的注意事项!!!

        在使用test()方法匹配正则时,使用了全局匹配,找到的是第一次第一个满足条件的内容。并且将这个位置的下标记录在正则中。第二次匹配时根据上次记录的下标继续向后匹配查找,直到查找不到返回false,则从索引下标0开始重新查找。

案例1:

    // 当使用全局匹配时
    var reg=/a/g;
    //                    012345
    console.log(reg.test("cdabac"));//true
    console.log(reg.lastIndex);//索引下标为3
    console.log(reg.test("cdabac"));//true
    console.log(reg.lastIndex);//索引下标为5
    console.log(reg.test("cdabac"));//false
    console.log(reg.lastIndex);//索引下标为0
    console.log(reg.test("cdabac"));//true
    console.log(reg.lastIndex);//索引下标为3
    console.log(reg.test("cdabac"));//true
    console.log(reg.lastIndex);//索引下标为5
    console.log(reg.test("cdabac"));//false
    console.log(reg.lastIndex);//索引下标为0

案例2:以下这个写法每次都会创建一个新的正则表达式查找。就不会存在向上的案例那样继续根据上次记录的下标继续向后匹配查找的情况。

    // 每次都会创建一个新的正则表达式查找
    console.log(/a/g.test("cdabac"));//true
    console.log(/a/g.test("cdabac"));//true
    console.log(/a/g.test("cdabac"));//true
    console.log(/a/g.test("cdabac"));//true
    console.log(/a/g.test("cdabac"));//true

  exec()方法 和 test()方法 使用全局查找时相同。只是 exec()方法没有查找到返回null

案例:

    var reg=/a/g;
    console.log(reg.exec("cdabac"));
    console.log(reg.exec("cdabac"));
    // 没有查找到返回null
    console.log(reg.exec("cdabac"));

4.4.2 字符串的方法中可以使用正则表达式的方法

  1. match(正则表达式) 检索字符串与正则表达式进行匹配的结果。返回值是一个 数组,其内容取决于是否存在全局(g)标志,如果没有匹配,则返回 null
  2. matchAll() :返回一个迭代器,该迭代器包含了检索字符串与 正则表达式 进行匹配的所有结果(包括捕获组)。
  3. replace() 字符串替换。
  4. replaceAll() : 替换所有结果
  5. search() 查找索引下标只查找第一个
  6. split() 字符串分割。

1. match(正则表达式)专用于正则表达式。

如果不使用g全局匹配类似于exec()方法

如果使用g全局匹配则会把所有匹配的结果放在一个数组中。

案例:

    console.log("abcacd".match(/a../g));

    console.log("abcacd".matchAll(/a../g));

​ 2. matchAll()返回一个迭代器,使用for of遍历这个迭代器可以看到多次使用exec()的结果。

    for(var value of "abcacd".matchAll(/a../g)){
        console.log(value);
    }

​3.  replace() 字符串替换。

案例1:
    var str="abcacd";
    //这里是普通的字符串查找
    console.log(str.replace("a","0"));//0bcacd
    //这里是使用了正则表达式查找
    console.log(str.replace(/a/,"0"));//0bcacd
    console.log(str.replace(/a/g,"0"));//0bc0cd
    str=str.replace(/a../g,function(item,index,s){
        // 如果下标是3返回”000“
        if(index===3) return "000";
        // 否则返回原查找到字符
        return item;
    })
    console.log(str);//abc000

-----------------------------------
案例2:
     // 将下面str的字符串变成"ab0ac1"
    var str="abac";
   
    str=str.replace(/a./g,function(item){
        console.log(item);//ab ac
        if(item==="ab")return item+0;
        return item+1;
    })
    console.log(str);//ab0ac1

4. replaceAll() 替换所有结果

    var str="abac";
    str=str.replaceAll(/a./g,"a0");
    console.log(str);//a0a0

    str=str.replaceAll(/a./g,function(item){
        console.log(item);//a0 a0
    });


    str=str.replaceAll("a","0")
    console.log(str);//undefinedundefined

5. search() 查找索引下标只查找第一个

    // search 与indexOf类似
    //案例1:
    var str="abac";
    console.log(str.search("a"));//索引下标为0
    console.log(str.search(/a/g));//索引下标为0
   
    //案例2:
    var str="abac";
    var reg=/a/g;
    console.log(str.search(reg));//索引下标为0

    //案例3:
    var str="babd";
    console.log(str.search(/.a/g));//索引下标为0

​6. split() 字符串分割。

    var str="ab|cd|ef&aa&cc";
    console.log(str.split("|"));
    // 部分字符在正则表达式中有自己的含义,为了恢复这个字符串本身的字符需要再前面加上\ 转义
    // \|  这个是字符 |    
    // |  是或者的意思
    // & 就是字符&
    console.log(str.split(/\||&/));

5. 正则表达式的模式(方括号+())

方括号用于查找某个范围内的字符。 正则中只有unicode编码相连的才可以使用。

  1. [abc] :查找方括号之间的任何字符
  2. [^abc] :查找任何不在方括号之间的字符。
  3. [0-9]:查找任何从 0 至 9 的数字可以使用 \d 代替。
  4. [^0-9] 查找除了所有数字的字符。可以使用 \D 代替。
  5. [a-z] : 查找任何从小写 a(97) 到小写 z(123) 的字符
  6. [A-Z]:查找任何从大写 A(65) 到大写 Z(93) 的字符
  7. [a-zA-Z] :查找全部英文字母字符
  8. [a-zA-Z0-9_] :查找小写字母大写字母数字下划线可以使用 \w 代替。
  9. [^a-zA-Z0-9_]:查找除了小写字母大写字母数字下划线可以使用 \W 代替。

  10. [^\^]:除了^ 以外的字符。

  11.  [a^c] :如果^不在第一位表示正常的^字符

  12. [adgk] :查找给定集合内的任何字符。
  13. [^adgk]:查找给定集合外的任何字符。
  14. (red|blue|green):查找任何指定的选项。

​注意!!!

以下是错误写法:

  1. [a-Z] 错误。 正则中只有unicode编码相连的才可以使用。
  2. [A-z] 错误。 正则中只有unicode编码相连的才可以使用。
  3. [1-31] 错误。方括号中只能匹配一个字符   [1-31] ---> 1-3 1

案例1:

<body>
    <input type="text">
    <script>
        var input = document.querySelector("input");
        input.addEventListener("input", inputHandler);

        function inputHandler(e) {
            // 只要有\w(小写字母大写字母数字下划线)就是正确
            if (/\w/g.test(input.value)) {
                input.style.borderColor = "green";
            } else {
                input.style.borderColor = "red";
            }
        }
    </script>
</body>

 ​​​​​​案例2:

<body>
    <input type="text">
    <script>
        var input = document.querySelector("input");
        input.addEventListener("input", inputHandler);

        function inputHandler(e) {
            // 如果有非a-z 就会绿色
            if (/[^a-z]/g.test(input.value)) {
                input.style.borderColor = "green";
            } else {
                input.style.borderColor = "red";
            }
        }
    </script>
</body>

​ ​​​​​​案例3:

console.log("a".match(/[a^c]/g));//^不是不包含的含义了,所以能找到
console.log("a".match(/[^ac]/g));//^不包含的含义,所以找不到

 ​ ​​​​​​案例4:​

<body>
    <input type="text">
    <script>
        var input = document.querySelector("input");
        input.addEventListener("input", inputHandler);

        function inputHandler(e) {
            input.value = input.value.replace(/[^a-z]/g, "");
        }
    </script>
</body>

 案例5:空白字符可以用于切割。

var str = "i like javascript";
console.log(str.split(" "));
console.log(str.split(/\s/));
console.log(str.match(/\s/g));

 

​案例6:空白字符可以用于切割。

var str = "  asdasd   asdad   asdads   asda      ";

str = str.replace(/\s/g, "")
console.log(str);
console.log(str.trim());//删除字符串前后空格
console.log(str.trimLeft());//删除字符串前空格
console.log(str.trimRight());//删除字符串前空格

案例7:去掉空格切割 

var str = "  asdasd   asdad   asdads   asda      "
console.log(str.match(/\S/g));
console.log(str.split(""));

案例8:数字

​/\d\d\d\d-\d\d-\d\d/  可以表示 2024-08-24

6. 正则的量词(用于字符串重复)

6.1 量词表

量词描述
n+

匹配任何包含至少一个 n 的字符串。+ 代表 至少有一次 或者 多次。

n*

匹配任何包含零个或多个 n 的字符串。 * 代表 没有 或者 有多次。

n?

匹配任何包含零个或一个 n 的字符串。 ?代表 有 或者 没有。

{n}n是几,就以n个字符为一组的重复。
n{X}

匹配包含 X 个 n 的序列的字符串。

n{X,}

X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。

n{X,Y}

X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。

n$匹配任何结尾为 n 的字符串。
^n匹配任何开头为 n 的字符串。
?=n匹配任何其后紧接指定字符串 n 的字符串。
?!n匹配任何其后没有紧接指定字符串 n 的字符串。

 6.2 {n} 重复n次详解

案例1:

// /\d{2}/  数字重复2次
console.log("ab1234".match(/\d{2}/g));

 

案例2:将"abcdefgh" 变成  ["ab","cd","ef","gf"]。

var str= "abcdefgh"
console.log(str.match(/\w{2}/g));

案例3:将"18617809865"改成 "186 1780 9865"

var str="18617809865";
console.log(str.match(/(\d{3})(\d{4})(\d{4})/));
console.log( str.match(/(\d{3})(\d{4})(\d{4})/).slice(1).join(" "));
        

 注意!!!

  1. a{1}/a/相同。
  2. /a{0}/ 表示a没有,就是表示一个""
  3. 每个字符之间有空字符,在字符起始位置结束位置也有空字符
  4. 任何字符{0} 都代表""。

6.3 贪婪匹配重复

 /a{n,m}/ : a重复n-m次 ,n是最小重复次数,m是最大重复次数,会优先找最大的。

​案例:

console.log("aaaaaa".match(/a{2,5}/g));
console.log("asdasdasdasda".match(/\w{3}/g));
console.log("asdasdasdasda".match(/\w{3,5}/g));

 {0,1}:表示最少0次,最多1次,有或者没有都可以。

案例: 

//这里表示u匹配0次或1次都可以。换句话说,u可以有也可以没有
console.log(/colou{0,1}r/.test("colour"));//true
console.log(/colou{0,1}r/.test("color"));//true

 /a{n,}/ : 表示a至少重复n次,最多无限次。

案例: 

console.log("aaaaaaaaa".match(/a{2,}/g));
// 至少1次,可以查找无限次
console.log("aaaaaaaaa".match(/a{1,}/g));

 案例:查找一个数字,不知道是第几位

<body>
    <input type="text">
    <script>
        var input = document.querySelector("input");
        input.addEventListener("input", inputHandler);

        function inputHandler(e) {
            if (/[a-zA-Z]{0,}\d/g.test(input.value)) {
                input.style.borderColor = "green";
            } else {
                input.style.borderColor = "red"
            }

        }
    </script>
</body>

​案例:

// 希望判断字符串中是否包含小写英文字母
console.log(/[^a-zA-Z]{0,}[a-z]/.test("1231231a23"));//true

// 至少在第1位以后包含英文字符
console.log(/[^a-zA-Z]{1,}[a-z]/.test("123123123"));//false
console.log(/[^a-zA-Z]{1,}[a-z]/.test("a123123123"));//false
console.log(/[^a-zA-Z]{1,}[a-z]/.test("1a23123123"));//true

{0,1}  ? 有或者没有

{0,}  *  没有或者有多次

{1,}  +  至少有一次或者多次

let str = "asdjad    asdkja    adsakj    asdkj";
//表示非空白字符,匹配一次或多次,使用“”替换到多个“”
str = str.replace(/\s+/g, " ")
console.log(str);//"asdjad asdkja adsakj asdkj"

6.4 非贪婪匹配重复

非贪婪匹配:找到对应位置结束的。非贪婪匹配都会有一个结束字符作为控制

非贪婪匹配的情况一:匹配范围比较大可能包含了后面的内容

非贪婪匹配的情况二:?后有一个相对结束对应的字符

情况一的案例:

var str = "中国的四大古典名著有《西游记》、《水浒》、《三国演义》、《红楼梦》";
//匹配《》中的内容有或者没有
console.log(str.match(/《[^《》]*》/g));

情况二的案例: 

var str = "中国的四大古典名著有《西游记》、《水浒》、《三国演义》、《红楼梦》";
//匹配《》中的内容有一个任意的字符或多个任意的字符遇到后》结束
console.log(str.match(/《.*?》/g));

案例:

var str = "asdashd123123csjkdhasd12312312sadasd123123";
//匹配一个或多个字符(大写字母+小写字母+数字),遇到数字则结束。
console.log(str.match(/\w+?\d/g));

案例:

var str = "adasd'bbbb'asdasd'12312313'";
//匹配‘’中一个任意字符或多个字符遇到’则结束
console.log(str.match(/'.+?'/g));

案例:

var str = "2024-02-20";
//匹配非空白字符一次或多次,遇到-则结束
console.log(str.match(/\d+-?/g));

//匹配一个任意字符一次或多次遇到-则结束
console.log(str.match(/.+?-/g));

7. 起始结束和或者(|)

 [^] :反义在[ ]中开始叫反义  ,在正则表达式开始叫做起始。

 /^/ 规定字符以某个内容开始

/$/:放在正则表达式的最后,叫做以什么内容结束。例如:/a$/:以a结束。

 | : 在多个字符串任选其中某个字符串

 /a||b/ : a 或者 "" 或者 b。

开始案例:

//字符串必须由a开始
console.log(/^a/.test("abc"));//true
console.log(/^a/.test("cabc"));//false

​结束案例:

console.log(/a$/.test("asdasda"));//true
console.log(/a$/.test("asdasd"));//false

| 的案例:

console.log(/ab|cd/.test("ab"));//true

 /a||b/ 的案例:

console.log("acdb".match(/a||b/g));
console.log("acdb".match(/|a|b/g));//先查""
console.log("acdb".match(/a|b|/g));//先查a,再查b,最后查""

综合案例:

//指abc这个字符串包含了abc这个正则表达式
console.log(/abc/.test("abc"));//true
//abc必须等于abc
console.log(/^abc$/.test("abc"));//true

 

两个一起使用的案例:

 

​8.群组

8.1 什么是群组

群组: 使用()括起来的就是群组。被()括起来的内容作为整体看

8.2 群组取值

数组的第0项就是查找到所有满足正则内容。

第1项-第n项都是每个()群组的独立内容。

案例1:

console.log("13890790654".match(/^(\d{3})(\d{4})(\d{4})$/));
       

案例2:

console.log("a=4".match(/^(\w+)=(\d+)$/));
      

案例3:

console.log("ahjdgshaskjdhakjsdh".match(/^(\w{3})\w+(\w{4})$/));

案例4:

// 在使用match不能使用g来取多个群组内容, exec可以
console.log(/^(\d{3})(\d{4})(\d{4})$/g.exec("13890790654"));

 案例5:

var str = "2[ab]3[cd]";
var str = "2[ab]";
console.log(str.match(/(\d+)\[(\w+)\]/g));
console.log(str.matchAll(/(\d+)\[(\w+)\]/g));
for (let value of str.matchAll(/(\d+)\[(\w+)\]/g)) {
    console.log(value);
}

8.3 断言

断言:判断满足条件。

/a(?=b)/ :后置肯定断言 ,判断a后面紧跟一个b,获取这个a。

/a(?!b)/ :后置否定断言,判断a后面紧跟不是b,获取这个a。

/(?<=b)a/ :前置肯定断言,判断a前面紧跟是一个b 获取这个a。

/(?<!b)a/ :前置否定断言,判断a前面紧跟不是b 获取这个a。

案例:

console.log("acabad".replace(/a/g, "0"));//"0c0b0d"
console.log("acabad".replace(/a(?=b)/g, "0"));//"ac0bad"
console.log("acabad".replace(/a(?!b)/g, "0"));//"0cab0d"

console.log("cabada".replace(/(?<=b)a/g, "0"));//"cab0da"
console.log("cabada".replace(/(?<!b)a/g, "0"));//"c0bad0"

8.4 低级、中级、高级密码

1. 低级密码

 /^\d{8,16}$|^[a-z]{8,16}$|^[A-Z]{8,16}$/

2.  中级密码

 /^(?=\D+\d)(?=.*[a-z])[a-zA-Z0-9_.@!]{8,16}$|^(?=\D+\d)(?=.*[A-Z])[a-zA-Z0-9_.@!]{8,16}$|^(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9_.@!]{8,16}$/

3. 高级密码 :首字母不能是数字,但是整个密码中必须包含数字小写字母大写字母,可以使用!@._,8-16位。

/^(?=\D+\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9_.@!]{8,16}$/

(?=\D+\d) 条件起始字符必须是非数字1个以上,后面包含有数字  ”a1“  "asdasd1"。

(?=.*[a-z]) 条件起始字符 .*任意字符任意多个后面至少有一个小写字母a-z  "ab" "Aa"。

(?=.*[A-Z]) 条件起始字符 .*任意字符任意多个后面至少有一个大写字母A-Z  "ab" "Aa"。

这三个条件是并且关系。

[a-zA-Z0-9_.@!]{8,16} 这些字符总共8-16。

 8.5  群组重复

(a)\1*  :0个以上重复。

(a)\1+ : 1个以上重复。

案例:

//将 "aaaaabbbbbcccccccd"变成["aaaaa", "bbbbb", "ccccccc"]
let str = "aaaaabbbbbcccccccd";

console.log(str.match(/(\w)\1+/g));
console.log(str.match(/(\w)\1*/g));

 8.6 群组变量

 使用方法 :(?<变量名>n)

案例:

let str = "user=xietian&b=4";
console.log(str.match(/(?<name>\w+)=(?<value>\w+)/));
console.log(/(?<name>\w+)=(?<value>\w+)/.exec(str));
let arr = []
for (let value of str.matchAll(/(?<name>\w+)=(?<value>\w+)/g)) {
      arr.push(value.groups);
}
console.log(arr);

 案例:将 '2[3[ab]4[2[c]3[d]]]'变成"abababccdddccdddccdddccdddabababccdddccdddccdddccddd"

let str = '2[3[ab]4[2[c]3[d]]]'

function parse(str) {
    if (!/\d+\[\w+\]/.test(str)) return str;
          return parse(str.replace(/(\d+)\[(\w+)\]/, function (item, a, b) {
               return b.repeat(a)
          }))
     }
str = parse(str);
console.log(str);

8.7 年月日的验证案例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form action="">
      <input type="text" id="year" />
      <input type="text" id="month" />
      <input type="text" id="day" />
    </form>

    <script>
      var form = document.querySelector("form");
      form.addEventListener("input", inputHandler);

      function inputHandler(e) {
        let input = e.target;
        let bool = false;
        if (/^year$/.test(input.id)) {
          let date = new Date();
          let year = date.getFullYear() % 2000;
          let a = ~~(year / 10);
          let b = year % 10;
          bool = new RegExp(
            `^19\\d{2}$|^20[0-${a - 1}]\\d$|^20${a}[0-${b}]$`
          ).test(input.value);
          input.style.borderColor = bool ? "green" : "red";
          input.bool = bool;
        } else if (/^month$/.test(input.id)) {
          bool = /^[1-9]$|^1[0-2]$/.test(input.value);
          input.style.borderColor = bool ? "green" : "red";
          input.bool = bool;
        }

        if (
          Array.from(form.children)
            .slice(0, 2)
            .every((item) => item.bool)
        ) {
          let year = form.children[0].value;
          let month = form.children[1].value;
          let date = new Date(Number(year), Number(month), 0);
          let day = date.getDate();
          let a = ~~(day / 10);
          let b = day % 10;
          let bool1 = new RegExp(
            `^[1-9]$|^1\\d$|^2[0-${a > 2 ? "9" : b}]$` +
              (a > 2 ? `|^3[0-${b}]$` : "")
          ).test(form.children[2].value);
          form.children[2].style.borderColor = bool1 ? "green" : "red";
        }
      }
    </script>
  </body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2089088.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SRA ToolKit(v 3.1.1)安装和使用(Bioinformatics tools-032)

01 检索数据 run就是数据&#xff0c;如SRR26717485 SRA 档案数据通过 SRA 加载过程进行标准化&#xff0c;并由 SRA 工具包用于读取和生成如 FASTQ、SAM 等格式。默认的工具包配置使其能够通过登录号查找和检索 SRA 运行数据。 现在&#xff0c;公共 SRA 文件可以通过 GCP 和…

[WCT系列(四):BLASTSyncEngine

WCT系列&#xff08;一&#xff09;&#xff1a;WindowContainerTransaction类详解 WCT系列&#xff08;二&#xff09;&#xff1a;SyncTransactionQueue类详解 WCT系列&#xff08;三&#xff09;&#xff1a;WindowOrganizerController WCT系列&#xff08;四&#xff09;&a…

分治,CF 768B. Code For 1

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 https://codeforces.com/problemset/problem/768/B 二、解题报告 1、思路…

python-读取word中的内容

doc Document(rD:\xxxx\xxxx\xxx.docx) #读取word中所有内容 for p in doc.paragraphs print(p,p.text) #读取指定段落中的所有run(文字块) for run in doc.paragraphs[1].runs: print(run,run.text) #读取word中所有表格内容 for 表格 in doc.tables: print(表格) for 行 in …

什么是家庭全光组网和企业全光组网,两者有什么区别?

家庭全光组网和企业全光组网虽然都是基于光纤技术来实现高速网络连接&#xff0c;但它们在应用场景、规模、需求和技术细节上存在一些差异。 家庭全光组网 目标用户&#xff1a;面向个人家庭用户。 规模&#xff1a;一般为单个住宅内的网络覆盖&#xff0c;或者小范围内的多个房…

零基础泛微二开指南

前言 在泛微系统上开发一个自定义post接口 准备 首先准备工作要做好&#xff0c;安装一个泛微&#xff0c;之后所有的操作要在泛微的安装目录操作 参考官网安装&#xff0c;挺麻烦的&#xff1b; IDEA 1、直接新建项目 new ->Project from Existing Sources.直接打开泛…

uniapp微信小程序page-container导致滚动失效/向下偏移,返回上一页/左滑取消返回上一页

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 前提&#xff1a; 使用uniapp来做的微信小程序 有两级tab页面 要求手机的两边往中间滑时 要求&#xff08;调用手机的物理返回按钮--有震动感&#xff09; 返回上一页。具体如下图箭头所示&#xf…

数据防泄漏软件10款超好用推荐|2024数据防泄漏软件排名

在2024年&#xff0c;数据防泄漏软件市场涌现了多款优秀的产品&#xff0c;它们通过不同的技术手段和策略&#xff0c;为企业提供全面的数据安全保护。以下是10款超好用的数据防泄漏软件推荐及简要排名。 1.安企神 特点&#xff1a;专为企业设计的数据安全防护工具&#xff0c…

【零知识证明】MiMC哈希函数电路

1 哈希电路 哈希函数电路实现&#xff1a; pragma circom 2.0.0;// y (x k c) ^ 5 // 输入信号x, k &#xff0c;常量c // base x k c // base2 base * base // base4 base2 * base2 // base5 base *base4 // 输出 ytemplate MIMC5(){signal input x;signal input k…

使用Aqua进行WebUI测试(Pytest)——介绍篇

一、在创建时选择Selenium with Pytest 如果选择的是Selenium&#xff0c;则只能选择Java类语言 选择selenium with Pytest&#xff0c;则可以选择Python类语言 Environment 其中的【Environment】可选New 和 Existing New &#xff1a;选择这个选项意味着你希望工具为你创…

【Go函数详解】二、参数传递、变长参数与多返回值

文章目录 一、传递参数1. 按值传参2. 引用传参2.1 特殊情况2.1.1 切片slice2.1.2 字典map 二、变长参数1. 基本定义和传值1.1 基本定义1.2 传值1.2.1 普通传值1.2.2 传递切片 2. 任意类型的变长参数&#xff08;泛型&#xff09; 三、多返回值1. 命名返回值 一、传递参数 1. 按…

破解电商数据分析难题,优化运营策略的秘诀

在电商行业中&#xff0c;数据分析是不可或缺的一部分。它能帮助商家精准掌握市场动态&#xff0c;优化运营策略&#xff0c;从而提升销售业绩。然而&#xff0c;面对大量复杂的数据&#xff0c;许多电商运营者往往不知道从哪里开始分析。那么&#xff0c;电商运营究竟如何有效…

优可测白光干涉仪助力红外探测行业发展——晶圆衬底检测

从18世纪红外线被发现&#xff0c;到19世纪红外探测器的发明。至今&#xff0c;随着工艺更新迭代&#xff0c;红外探测器朝着多波段、大面阵、高分辨率、低成本量产快速发展。 今天&#xff0c;小优博士带您探索红外探测的奥秘。 一、红外线是什么 红外光是一种电磁波&#x…

【 OpenHarmony 系统应用源码解析 】-- Launcher 初体验

前言 最近因为业务需要&#xff0c;需要做一款 UI 定制的鸿蒙 Launcher&#xff0c;于是就开始了「找到代码」、「研究代码」、「魔改代码」的套路流程&#xff0c;仅以此文章作为知识备份和技术探讨所用&#xff0c;也希望能给其他小伙伴提供一些源码的解析思路&#xff0c;方…

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——8.stackqueuepriority_queue(模拟实现)

1.stack 可通过模板使用其他类来建立stack&#xff08;如vector&#xff0c;list&#xff09; #include<vector>namespace zone {template<class T,class container> //两个模板参数class stack{public:void push(const T& x){it.push_back(x); //使用it的p…

【Linux】命令简介------迅速掌握Linux命令

目录 Linux 命令 &#x1f354; ls命令 &#x1f354; cd 和 pwd命令 &#x1f354; 相对路径和绝对路径 &#x1f354; 文件/文件夹的创建以及文件内容的浏览 &#x1f354; 文件的复制,移动和删除 &#x1f354; 文件的查找 &#x1f354; grep 和管道 &#x1f354…

Windows11安装SqlLite、Navicat Premium 15连接SqlLite、Springboot集成SqlLite

一、Windows11安装SqlLite 1、下载安装包 地址&#xff1a;SQLite Download Page 2、压缩包解压 3、配置系统环境变量 4、验证安装是否成功 打开命令提示符&#xff0c;输入 sqlite3 5、创建数据库文件 新建文件重命名为你想要的数据库名称&#xff0c;文件后缀改为.db 二、…

【微信小程序】如何触发按钮事件,例如调起微信客服

需求 实现一个如下图的效果, 点击客服按钮, 调起微信客服功能, 需要和button组合使用 效果图 实现思路 客服只能通过button按钮调起, 所以我们需要写一个button按钮, open-type“contact”, 然后把它隐藏起来。给客服图标加一个label, 设置for“btnId”, 这样点击图片就会触…

微服务即时通讯系统环境搭建(客户端)

微服务即时通讯系统环境搭建(客户端) 前言 今天开始&#xff0c;我们要开一个新坑&#xff0c;我们将它称作微服务即时通讯系统。说到即时通讯系统&#xff0c;大家肯定能想到如同“微信”这样的app。那么没错&#xff0c;这次这个项目就会像微信一样&#xff0c;当然功能肯定…

Linux(CentOS8)系统安装mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz

一、下载获取 mysql安装包&#xff1b; MySQL :: Download MySQL Community Server (Archived Versions) 二、安装步骤 1、切换到安装目录下&#xff0c;并解压 tar -zxvf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz 2.移动解压后的文件并且重命名为mysql mv mysql-8.0.26…