正则表达式的位置,字符匹配

正则表达式

↓↓↓↓↓↓↓↓↓直接预览目录中图片版笔记即可,文字版可用于复制

目录


↑ ↑ ↑ ↑ ↑ ↑直接预览目录中图片版笔记即可,文字版可用于复制

来自 https://juejin.cn/post/6844903487155732494

图片版笔记

正则表达式的位置,字符匹配

正则表达式是匹配模式,要么匹配字符,要么匹配位置。

第一章 正则表达式字符匹配攻略

1 两种模糊匹配

            var string = "……,……,……"
            regex = / ...  /
//正则表达式
            string.match(regex) 
            //=> ["a1b", "a2b", "a3b"]

1.1 横向模糊匹配

横向模糊匹配:/ad{2,10}c/
(横向模糊指的是,一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。)
(表示匹配这样一个字符串:第一个字符是“a”,接下来是2到5个字符“b”,最后是字符“c”)
量词: {m,n}
(表示此字母连续出现最少m次,最多n次)
(量词在正则表达式中使用时可以限制前方字符的长度)
简写形式:
{m,} 表示至少出现m次。
{m} 等价于{m,m},表示出现m次。
? 等价于{0,1},表示出现或者不出现。记忆方式:问号的意思表示,有吗?

  • 等价于{1,},表示出现至少一次。记忆方式:加号是追加的意思,得先有一个,然后才考虑追加。
  • 等价于{0,},表示出现任意次,有可能不出现。记忆方式:看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。

    var regex = /ab{2,5}c/g;
    var string = "abc abbc abbbc abbbbc abbbbbc abbbbbbc";
    console.log( string.match(regex) ); 
    // => ["abbc", "abbbc", "abbbbc", "abbbbbc"]
    

全局匹配:/g
(在目标字符串中按顺序找到满足匹配模式的所有子串,强调的是“所有”,而不只是“第一个”。)

1.2 纵向模糊匹配

纵向模糊匹配:/a[123]c/
(纵向模糊指的是,一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。)
(表示该字符是可以字符“1”、“2”、“3”中的任何一个。)
字符组:[abv123%]
(字符组在正则表达式中使用时可以代替一个字符)

范围表示法: [1-6a-fG-M]
连字符:-
(来省略和简写)
需要匹配连字符怎么办?
要匹配“a”、“-”、“z”这三者中任意一个字符
[-az]或[az-]或[a-z]。连字符要么放在开头,要么放在结尾,要么反斜杠写在连字符前转义。

排除字符组:[^abc]
(表示是一个除"a"、“b”、"c"之外的任意一个字符。)
脱字符:^

\d就是[0-9]。表示是一位数字。记忆方式:其英文是digit(数字)。
\D就是[^0-9]。表示除数字外的任意字符。
\w就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。
\W是[^0-9a-zA-Z_]。非单词字符。
\s是[ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。
\S是[^ \t\v\n\r\f]。 非空白符。
.就是[^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号…中的每个点,都可以理解成占位符,表示任何类似的东西。

匹配任意字符:
[\d\D]、[\w\W]、[\s\S]和[^]

贪婪匹配和惰性匹配
贪婪匹配
(正则 /\d{2,5}/ ,表示数字连续出现2到5次。会匹配2位、3位、4位、5位连续数字。)
(但是其是贪婪的,它会尽可能多的匹配。)

惰性匹配,就是尽可能少的匹配:
⭐( /\d{2,5}?/ 表示,虽然2到5次都行,当2个就够的时候,就不在往下尝试了,只会匹配2位。)

通过在量词后面加个问号 ? 就能实现惰性匹配,因此所有惰性匹配情形如下:
{m,n}?
{m,}?
??
+?
*?
多选分支
具体形式如下:(p1|p2|p3),其中p1、p2和p3是子模式,用 |(管道符)分隔,表示其中任何之一。
用管道符链接的多个子模式就是多选分支,她是惰性匹配。

例如要匹配"good"和"nice"可以使用 /good|nice/。测试如下:

                var regex = /good|nice/g;
                var string = "good idea, nice try.";
                console.log( string.match(regex) ); 
                // => ["good", "nice"]

但有个事实我们应该注意,比如我用/good|goodbye/,去匹配"goodbye"字符串时,结果是"good":

                var regex = /good|goodbye/g;
                var string = "goodbye";
                console.log( string.match(regex) ); 
                // => ["good"]

而把正则改成/goodbye|good/,结果是:

                var regex = /goodbye|good/g;
                var string = "goodbye";
                console.log( string.match(regex) ); 
                // => ["goodbye"]

也就是说,分支结构也是惰性的,即当前面的匹配上了,后面的就不再尝试了。
⭐(/goodbye|good/表示匹配goodbye或good都可以,但匹配到goodbye后就不再判断是否有good了)
ex:匹配时间
以24小时制为例。
要求匹配:
23:59
02:07
分析:
共4位数字,第一位数字可以为[0-2]。
当第1位为2时,第2位可以为[0-3],其他情况时,第2位为[0-9]。
第3位数字为[0-5],第4位为[0-9]
正则如下:

        var regex = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;
        console.log( regex.test("23:59") ); 
        console.log( regex.test("02:07") ); 
        // => true
        // => true

如果也要求匹配7:9,也就是说时分前面的0可以省略。
此时正则变成:

        var regex = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/;
        console.log( regex.test("23:59") ); 
        console.log( regex.test("02:07") ); 
        console.log( regex.test("7:9") ); 
        // => true
        // => true
        // => true

⭐(?可以直接使用表示前方的数字可以省略)
\字符需要转义
[^\:<>|"?\r\n/]:
表示合法字符
要求匹配:
F:\study\javascript\regex\regular expression.pdf
F:\study\javascript\regex
F:\study\javascript
F:
var regex = /[a-zA-Z]:\([\:
<>|"?\r\n/]+\)([^\:<>|"?\r\n/]+)?$/;
console.log( regex.test(“F:\study\javascript\regex\regular expression.pdf”) );
console.log( regex.test(“F:\study\javascript\regex\”) );
console.log( regex.test(“F:\study\javascript”) );
console.log( regex.test(“F:\”) );
// => true
// => true
// => true
// => true

其中,JS中字符串表示\时,也要转义。

比如说匹配输入串
A: 101000000000100
使用 1.1 将会匹配到1010000000001,匹配方法: 先匹配至输入串A的最后,然后向前匹配,直到可以匹配到1,称之为贪婪匹配。
使用 1.
?1 将会匹配到101,匹配方法: 匹配下一个1之前的所有字符,称之为非贪婪匹配。

第二章 正则表达式位置匹配攻略

1.什么是位置呢?

位置是相邻字符之间的位置。比如,下图中箭头所指的地方:

2.如何匹配位置呢?

在ES5中,共有6个锚字符:
^ $ \b \B (?=p) (?!p)
2.1 ^和$
^(脱字符)匹配开头,在多行匹配中匹配行开头。
$(美元符号)匹配结尾,在多行匹配中匹配行结尾。
比如我们把字符串的开头和结尾用"#"替换(位置可以替换成字符!):

var result = "hello".replace(/^|$/g, '#');
console.log(result); 
// => "#hello#"

多行匹配模式时,二者是行的概念,这个需要我们的注意:

  var result = "I\nlove\njavascript".replace(/^|$/gm, '#');
  console.log(result);
  /*
  #I#
  #love#
  #javascript#
  */

也就是说,每行都有开头和结尾被匹配。

2.2 \b和\B

\b是单词边界,具体就是\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和KaTeX parse error: Undefined control sequence: \b at position 38: …esson_01.mp4"中的\̲b̲,如下: var result…之间的位置,必须是/w与开头或结尾之间产生\b
知道了\b的概念后,那么\B也就相对好理解了。
\B就是\b的反面的意思,非单词边界。
具体说来就是\w与\w、\W与\W、^与\W,\W与$之间的位置。

把所有\B替换成"#":

var result = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
console.log(result); 
// => "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"

2.3 (?=p)和(?!p)

(?=p),其中p是一个子模式,即p前面的位置。
比如(?=l),表示’l’字符前面的位置,例如:

var result = "hello".replace(/(?=l)/g, '#');
console.log(result); 
// => "he#l#lo"
而(?!p)就是(?=p)的反面意思,比如:
var result = "hello".replace(/(?!l)/g, '#');
console.log(result); 
// => "#h#ell#o#"

二者的学名分别是positive lookahead和negative lookahead。
中文翻译分别是正向先行断言和负向先行断言。
ES6中,还支持positive lookbehind和negative lookbehind。
具体是(?<=p)和(?<!p)。

锚字符指定正则中相对应位置上有什么
不匹配任何东西的正则:/.^/
因为此正则要求只有一个字符,但该字符后面是开头。

Ex:
(?=.[0-9])任意字符串后有一数字
(?=.
[a-z])任意字符串后有一小写字母
(?=.*[A-Z])任意字符串后有一大写字母

不匹配任何东西的正则/.^/
开头位置/(?=^)/
非开头位置/(?!^)/

包含数字大小写字母的6-12位密码:

“至少包含两种字符”的意思就是说,不能全部都是数字,也不能全部都是小写字母,也不能全部都是大写字母:

var reg = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)
^[0-9A-Za-z]{6,12}$/;
console.log( reg.test("1234567") ); // false 全是数字
console.log( reg.test("abcdef") ); // false 全是小写字母
console.log( reg.test("ABCDEFGH") ); // false 全是大写字母
console.log( reg.test("ab23C") ); // false 不足6位
console.log( reg.test("ABCDEF234") ); // true 大写字母和数字
console.log( reg.test("abcdEF234") ); // true 三者都有

同时包含两种类型字符,同时包含数字、小写字母和大写字母:

var reg = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/;
console.log( reg.test("1234567") ); // false 全是数字
console.log( reg.test("abcdef") ); // false 全是小写字母
console.log( reg.test("ABCDEFGH") ); // false 全是大写字母
console.log( reg.test("ab23C") ); // false 不足6位
console.log( reg.test("ABCDEF234") ); // true 大写字母和数字
console.log( reg.test("abcdEF234") ); // true 三者都有
上一篇:Web前端架构师


下一篇:正则使用