正则表达式之量词

  咱们知道,在正则表达式中,可使用[0-9]或\d来匹配单个数字字符,可是,若是须要验证一个更复杂的字符串呢,好比大陆地区的邮政编码。   不过邮政编码并无特别规定,只有由6个数字组成的字符串而已, 如246512,根据[0-9]或\d,咱们能够很快的实现匹配的正则表达式,\d\d\d\d\d\d。   从上能够看出,咱们重复用了6个单个字符来实现匹配,因为目前数字较少,看着还能够接受,那若是不是6个数字组成的,10个?20个?甚至是更多呢,显然这种方式是不行的,正则表达式提供了量词,用来限定出现的次数,能够很好解决这个问题。javascript

首先,看下量词的表示形式:java

量词的通常形式

表:通常形式

量词 说明
{n} 量词前面的元素必须出现n次
{n,m} 量词前面的元素至少出现n次,最多出现m次
{n,} 量词前面的元素至少出现n次,无上限
{,m} 量词前面的元素能够不出现,也能够出现,最多出现m次(javascript不支持这种写法)
```bash
    /^[0-9]{2}$/.test('12') // => true
    /^[0-9]{2}$/.test('123') // => false
    /^[0-9]{2,5}$/.test('123') // => true
    /^[0-9]{2,5}$/.test('123456') // => false
    /^[0-9]{2,}$/.test('123456') // => true
    /^[0-9]{0,5}$/.test('123456') // => false
    /^[0-9]{0,5}$/.test('12') // => true
    /^[0-9]{0,5}$/.test('') // => true
```
复制代码

注意:

一、{n,m}之间的逗号后面不能出现空格,不然没法正确匹配。 正则表达式

/^[0-9]{0, 5}$/.test('12') // => false

二、量词限定的出现次数通常都有明确下限,若是没有,则默认为0,因此推荐{,m}写成{0,m},这是通用的写法。 bash

/^[0-9]{,5}$/.test('12') // => false

经常使用量词

{n,m}是通用形式的量词,正则表达式还有3个经常使用的量词,分别是+?*,虽然形式不一样于{n,m},但功能确实相同的,能够看成是“量词的简介法”。编码

表:经常使用量词

经常使用量词 {n,m}等价形式 说明
* {0,} 可能出现,也可能不出现,出现次数没有上限
+ {1,} 至少出现次数为1,出现次数没有上线
? {0,1} 最多出现1次,有可能不出现(出现0次或1次)
```bash
    /^\d+(\.\d+)*$/.test('123') // => true
    /^\d+(\.\d+)*$/.test('123.123') // => true
    /^\d+(\.\d+)*$/.test('123.123.111') // => true
    /^\d+(\.\d+)*$/.test('123.') // => false
    /^travell?er$/.test('traveller') // => true
    /^<[^>]+>$/.test('<div>') // => true
    /^<[^>]+>$/.test('<b>') // => true
    /^<[^>]+>$/.test('<>') // => false
    /^travell?er$/.test('traveler') // => true
    /^travell?er$/.test('traveller') // => true
```
复制代码

在实际开发中,不少状况用这三种表示形式几乎能够知足,所以使用频率要高于{n,m}。spa

点号

正则中,有一个特殊的特殊的元字符,点号.,它能够匹配任意字符,除了换行符(\n)。 若是须要用点号匹配任意字符,则必须在单行内匹配,或者使用其余的方式来替代,如[\s\S]、[\w\W]或[\d\D]。 但在实际开发中,许多人为了图省事,不少状况下会这样使用,这样滥用点号将会带来一些问题。3d

如: bash new RegExp("^.*$").exec("quoted 'string '") new RegExp("^(([a-z]+)\\s')+$").exec("quoted 'string '") 如上,匹配的结果将会是整个字符串:"quoted 'string '",这就是咱们常说的贪婪模式。 要弄清楚为何会是这个结果,则必须了解表达式的匹配原理,以".*"为例。 在正则表达式中,点号.能够用来匹配除了换行符以外的全部字符,而*表示匹配的字符串长度没有限制,因此在".*"匹配过程当中,每遇到一个字符, ".*"均可以匹配,究竟是匹配它,仍是忽略它,将其留给最后的"来匹配呢? 答案是由量词来决定的,在正则表达式中量词分为几类,匹配优先量词(贪婪量词)和忽略优先量词(惰性量词)(还有一种支配量词,这里就不介绍了,请自行百度)code

匹配优先量词

匹配优先量词,顾名思义,在拿不许是否匹配某个字符时,优先尝试匹配,而且记下这个状态,以备未来“反悔”。 具体过程: 一开始,"匹配",而后到字符q,.*能够匹配q,也能够不匹配,但使用了匹配优先量词*,全部.*会尝试先匹配q,而且记录下这个状态。 接下来是字符字符u,.*能够匹配u,也能够不匹配,但使用了匹配优先量词*,全部.*会尝试先匹配u,而且记录下这个状态。 ... 轮到字符',.*能够匹配',也能够不匹配,但使用了匹配优先量词*,全部.*会尝试先匹配',而且记录下这个状态。 最后是字符串末尾的",.*能够匹配",也能够不匹配,但使用了匹配优先量词*,全部.*会尝试先匹配",而且记录下这个状态。 这个时候,字符串后面已经没有字符了,可是正则表达式中仍是有"没有匹配,因此只能查看以前保存的备用状态,看看能不能回退几步,以便匹配",因而让.*后退几步,以便让"能够匹配",发现正好能够匹配,因此整个匹配宣告结束,这个“反悔”的过程,专业术语叫回溯。 cdn

表达式

忽略优先量词

忽略优先量词,与匹配优先量词相反,在不肯定是否匹配某个字符时,会优先选择“不匹配”的状态,在尝试匹配表达式以后的字符,若是匹配失败,则再回溯,选择以前保存的“匹配的”状态,这样保证了匹配的正确性。 只须要把.*改成.*?便可变成忽略优先量词。 具体过程: 相似于匹配优先量词 这种匹配能够用于完成不少功能,好比匹配注释,标签等。blog

表:匹配优先量词与忽略优先量词

匹配优先量词 忽略优先量词
* *?
+ +?
? ??
{n} {n}?
{n,m} {n,m}?
{n,} {n,}?
{,m} {,m}?

转义

在正则表达式中,+?*等量词是特殊字符,具备特殊含义,可是有些状况下,只想表达字符自身,则须要转义,即在字符前加反斜线\。对于通常形式的量词{n,m},虽然含有特殊含义的字符不止一个,但转义时只须要给{添加反斜线\便可,如须要匹配{n,m},则是{n,m}。 注意:忽略优先字符不像通常形式字符{n,m}同样,只须要添加一个反斜线\,如*?,必须都要添加反斜线\,即正则表达式必须写做:*?,而不是*?,后者的意思是“*这个字符有可能出现,有可能不出现”。

表:各类量词的转义

量词 转义形式
* *
+ +
? ?
*? *?
+? +?
?? ??
{n} {n}
{n,m} {n,m}
{n,} {n,}
{,m} {,m}

除此以外,元字符点.也须要加反斜线\来进行转义。 因为点.表示除了换行符以外的字符,也包括点号(.),因此不少人忽略了对其转义,但若是忽略了对其转义,则在严格匹配点号时会出错。好比匹配小数(3.14)、IP地址(192.168.1.1)、Email地址(some@host.com)等,因此如果要匹配的文本包含点号,必定不要忘了对其进行转义,不然会出现以下的出错:

```bash
    /^\d+.\d+$/.test("3.14") // => true
    /^\d+.\d+$/.test("3@14") // => true
    /^\d+\.\d+$/.test("3.14") // => true
    /^\d+\.\d+$/.test("3@14") // => false
```
复制代码

正则分析

一、密码长度在6-12个字符之间 二、只能由小写字母,数字和横线组成 三、开头和结尾不能为横线 四、不能所有为数字 五、不容许有连续(2个及以上)的横线

/^(?!-)(?!\d+)([0-9a-z]{6,12}|([0-9a-z]+-?[0-9a-z]+)+)(?<!-)/.test('bdad-ss-e3')

相关文章
相关标签/搜索