並且写表示什么意思,正则表明式入门

2020-04-30 作者:网站首页   |   浏览(195)

时间: 2019-12-19阅读: 72标签: 正则

---恢复内容开始---

对于初学正则的同学来说,^$这两个看似简单的字符却在使用中总让匹配结果超出我们的预期,^什么时候表示行首什么时候表示反义?^ $两个一起写表示什么含义?今天我们就来详细聊聊这两个字符。

最简单的单独匹配一个单词,如匹配blue.需要使用b.它是元字符,代表着单词的开头或者结尾.只匹配一个位置.匹配单词blue.bblueb.

关于^与$

一些元字符
  • b匹配一个位置
  • .匹配除换行以为任意字符
  • *表示重复零次或更多次
  • d匹配一个数字
  • s匹配任意的空白符,如空格,制表符,换行符
  • w匹配数字,字母,汉子,还有下划线
  • ^匹配字符串的开始,$匹配字符串的结尾

先解释^与$概念,很简单的两句话,先留个印象。

举例
  • baw*b匹配以a开头的单词(有可能是abc,a正则,a_g_)
  • d 匹配一个或者更多连续的数字
  • bw{6}b匹配刚好6个单词的单词
  • ^d{5,12}$匹配5到12位数字

^ 脱字符:匹配开头,若存在多行匹配多行的行头。

重复的几种表示方法
  • *重复零或者任意更多次
  • 重复一次或更多次
  • ?零或者一次
  • {n}重复n次
  • {n,}n或者更多次
  • {n,m}n到m次

$ 美元符:匹配尾部,若存在多行匹配多行的尾部。

方括号的使用[]
  • [aeiou]匹配任何一个元音字母
  • [.?!]匹配其中一个标点符号
  • [0-9]匹配一个数字
  • [a-z 0-9 A-Z]

我们知道正则是一种匹配模式,要么匹配字符,要么匹配位置。这里我们得从这两种匹配情况分别解释这两个字符。

反义
  • W匹配任意非字母,非数字,非汉子,非下划线的字符
  • S匹配除了空白符的字符
  • D匹配任意非数字的字符
  • B匹配不是单词开头或结尾的位置
  • 在方括号里面使用^实现反义,[^a]匹配除了a以外的任意字符

1.从匹配字符角度

分枝条件| 正则表达式里的替换指的是有几种规则,如果满足了其中一种规则都应该当成匹配
  • 0d{2}-d{8}|0d{3}-d{7}匹配两种以连字符分割的电话号码
  • d{5}-d{4}|d{5}匹配美国的邮编,5位数字或者用连字号间隔的9位数字。

当用于匹配字符时,^与$更多是作为匹配出精准结果的辅助条件,我们先看个简单的例子:

之所以给出这个例子,是要注意,使用分枝条件时,顺序很重要。从左到右测试条件,一旦满足了某个条件,就不会去管后面的正则了。如果换成d{5}|d{5}-d{4},用这个去匹配时,只能匹配到5位数字,或者9位数字的前五位
'123'.match(/d/g);//[1,2,3]
后向引用

还记得前面分组用的小括号吗?后向引用就是给小括号编上号,从左到右依次为1,2...

  • b(w )bs 1b这里的1匹配前面的单词
  • 可以给子表达式自定义名字,使用?<name>例如?<word>w 调用的时候使用k<word>

很好理解,全局(注意结尾有个g)匹配单个任意数字,很明显1,2,3都符合条件,所以这里找到了三个匹配结果;我们分别添加 ^ 与 $ 再看:

零宽断言
  • (?=exp) //匹配exp前面的位置
    • bw (?=ingb)匹配以ing结尾的单词前面的部分
  • (?<=exp) //匹配exp后面的位置
    • (?<=bre)w b //匹配以re开头的单词后面的部分
  • (?!exp) //匹配后面跟的不是exp的位置
    • d{3}(?!d) //匹配三位数字,而且三位数字后面不能是数字
  • (?<!exp) //匹配前面跟的不是exp的位置
    • (?<![a-z])d{7}匹配前面不是小写字母的七位数字
  • 假如想要在一串很长的数字中每三位数字间加一个逗号,可以这样来匹配位置((?=d)d{3})*b
  • 匹配以空白符间隔的数字(?<=s)d(?=s)
'123'.match(/^d/g);//[1]'123'.match(/d$/g);//[3]
贪婪与懒惰
  • 默认贪婪匹配,如a.*b用在aababb上的话,会匹配整个字符串
  • 想要实现懒惰匹配,需要加上问号a.*?b这样只会匹配aab
  • *? 重复任意次,但尽可能少重复
  • ? 重复1次或更多次,但尽可能少重复
  • ?? 重复0次或1次,但尽可能少重复
  • {n,m}? 重复n到m次,但尽可能少重复
  • {n,}? 重复n次以上,但尽可能少重复

---恢复内容结束---

此时 ^d 只能匹配到1,而 d$ 只能匹配到3,你肯定就纳闷了,不对啊,我正则后面不是有个g表示全局匹配吗,怎么只匹配一个了呢?以 ^d为例,此时的匹配条件其实是找开头位置后的一个任意数字,d$ 表示匹配结尾前的一个任意数字。开头和结果对于一个不换行的字符串都只有一个,所以自然只能找到一个数字了,现在能理解前面所说的^$作为辅助条件的意思了吗。

最简单的单独匹配一个单词,如匹配blue.需要使用b.它是元字符,代表着单词的开头或者结尾.只匹配一个位置.匹配单词blue.bblueb.

那么我们现在将数字换行,再看:

一些元字符
  • b匹配一个位置
  • .匹配除换行以为任意字符
  • *表示重复零次或更多次
  • d匹配一个数字
  • s匹配任意的空白符,如空格,制表符,换行符
  • w匹配数字,字母,汉子,还有下划线
  • ^匹配字符串的开始,$匹配字符串的结尾

'12n34'.match(/^d/mg);//[1,3]'12n34'.match(/d$/mg);//[2,4]
举例
  • baw*b匹配以a开头的单词(有可能是abc,a正则,a_g_)
  • d 匹配一个或者更多连续的数字
  • bw{6}b匹配刚好6个单词的单词
  • ^d{5,12}$匹配5到12位数字

由于存在换行,导致现在有两个开头位置和两个结尾位置(注意匹配中使用了m,表示换行匹配),所以匹配结果也变成了两个,不难理解吧。

重复的几种表示方法
  • *重复零或者任意更多次
  • 重复一次或更多次
  • ?零或者一次
  • {n}重复n次
  • {n,}n或者更多次
  • {n,m}n到m次

2.从匹配位置角度

方括号的使用[]
  • [aeiou]匹配任何一个元音字母
  • [.?!]匹配其中一个标点符号
  • [0-9]匹配一个数字
  • [a-z 0-9 A-Z]

正则除了根据规则匹配对应的字符,还有一个强大的功能就是匹配位置。什么是位置呢?以字符 1234 为例,每个箭头都代表一个位置,其中第一个箭头的位置就是 脱字符 ^,结果位置就是美元符$, 如下图:

反义
  • W匹配任意非字母,非数字,非汉子,非下划线的字符
  • S匹配除了空白符的字符
  • D匹配任意非数字的字符
  • B匹配不是单词开头或结尾的位置
  • 在方括号里面使用^实现反义,[^a]匹配除了a以外的任意字符

所以当我们在匹配位置时,^$也成为了我们需要匹配的结果,例如,我需要将 1234 首尾位置加上花朵:

分枝条件| 正则表达式里的替换指的是有几种规则,如果满足了其中一种规则都应该当成匹配
  • 0d{2}-d{8}|0d{3}-d{7}匹配两种以连字符分割的电话号码
  • d{5}-d{4}|d{5}匹配美国的邮编,5位数字或者用连字号间隔的9位数字。
'1234'.replace(/^|$/g, '?');// "?1234?"
之所以给出这个例子,是要注意,使用分枝条件时,顺序很重要。从左到右测试条件,一旦满足了某个条件,就不会去管后面的正则了。如果换成d{5}|d{5}-d{4},用这个去匹配时,只能匹配到5位数字,或者9位数字的前五位

当然,在匹配位置时^与$也是帮助我们精确位置的辅助条件,比如常用的千位分隔符正则:

后向引用

还记得前面分组用的小括号吗?后向引用就是给小括号编上号,从左到右依次为1,2...

  • b(w )bs 1b这里的1匹配前面的单词
  • 可以给子表达式自定义名字,使用?<name>例如?<word>w 调用的时候使用k<word>
'12345678'.replace(/(?!^)(?=(d{3}) $)/g, ',');// "12,345,678"
零宽断言
  • (?=exp) //匹配exp前面的位置
    • bw (?=ingb)匹配以ing结尾的单词前面的部分
  • (?<=exp) //匹配exp后面的位置
    • (?<=bre)w b //匹配以re开头的单词后面的部分
  • (?!exp) //匹配后面跟的不是exp的位置
    • d{3}(?!d) //匹配三位数字,而且三位数字后面不能是数字
  • (?<!exp) //匹配前面跟的不是exp的位置
    • (?<![a-z])d{7}匹配前面不是小写字母的七位数字
  • 假如想要在一串很长的数字中每三位数字间加一个逗号,可以这样来匹配位置((?=d)d{3})*b
  • 匹配以空白符间隔的数字(?<=s)d(?=s)

这段正则的意思,就是从右往左找,每隔三位数字前面的位置替换成逗号,同时排除字段头部位置,因为当不排位开头位置,只要字符长度是三的倍数,就会导致头部也会出现逗号的尴尬局面,例如:

贪婪与懒惰
  • 默认贪婪匹配,如a.*b用在aababb上的话,会匹配整个字符串
  • 想要实现懒惰匹配,需要加上问号a.*?b这样只会匹配aab
  • *? 重复任意次,但尽可能少重复
  • ? 重复1次或更多次,但尽可能少重复
  • ?? 重复0次或1次,但尽可能少重复
  • {n,m}? 重复n到m次,但尽可能少重复
  • {n,}? 重复n次以上,但尽可能少重复
'123456789'.replace(/(?=(d{3}) $)/g, ',');// ",123,456,789"

所以针对千位分隔符正则中的 ^ 与 $ 而言,^起到了排除开头位置的作用,而$起到了改变正则匹配的方向,由默认的从左到右变成了从右到左每隔三位的查找。

3.反义字符组

^除了作为脱字符表示从头匹配,开头位置两个含义外,还能作为反义字符使用,例如,我想匹配除了123之外的任意字符:

/[^123]/.test(1); //false/[^123]/.test(2); //false/[^123]/.test(3); //false/[^123]/.test(4); //true

这里[^123]就表示除了123之外的意思,那么我们怎么知道^什么时候表示反义,什么时候表示开头位置呢?很简单,因为当它只有放在字符组中时才叫反义字符组,所以当然是只有出现在[]中时才是反义的意思。

4.^与$同时出现在正则前后表示什么?

对于新手而言,^$同时出现确实有点误解人,毕竟我们前面说^表示从左到右,$能起到从右到左的作用,同时出现难道匹配左右夹击?其实同时写时只是限制字符的起点与终点,我们来看个例子:

/123/.test(' 123 '); //true/^123$/.test(' 123 '); //false

第一个输出true,这是因为被检测的字段只要有123这三个字段就行了,不关心你123前后还有什么。而第二个我们利用^$限时了字符的两端,也就是说如果你test想为真,那么你的字符开头后面必须是1,结尾前面必须是3,字符的开头结尾被固定死了。一般在验证表单输入是否正则,我们都会加上^$。

本文由yzc216亚洲城发布于网站首页,转载请注明出处:並且写表示什么意思,正则表明式入门

关键词: yzc216亚洲城