常见正则问题


正则

问题:
require.context解析store的时候,看到replace正则,来搞清楚正则详细内容(忘记太多了…)

const req = require.context('./modules',true,/\.js/)
let modules = []
req.keys().forEach(modulePath=>{
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+/,'$1')
  modules[moduleName] = req(modulePath).default
})

全局、忽略大小写

var str = "abcd-abcd-abcd";
str.replace(/a/g, "e") // ebcd-ebcd-ebcd
str.replace(/A/i, "e") // ebcd-abcd-abcd
str.replace(/A/gi, "e") // ebcd-ebcd-ebcd

testexecmatch区别

参考:https://blog.csdn.net/weixin_34228387/article/details/94470261

  • 正则的方法:test和exec
  • string的方法:match(和replace使用正则的时候有点像,eg:$1,$2等等)

所以调用方式也不一样:

reg.test(str)   
reg.exec(str)
str.match(reg)

返回不同:

  • 返回bool:test;
  • 返回null或者数组:exec和match;
console.log('非全局:','t3abc4,58abc6'.match(/\d+/)) // ['3', index: 1, input: 't3abc4,58abc6', groups: undefined]
console.log('全局:','t3abc4,58abc6'.match(/\d+/g)) // ['3', '4', '58', '6']

console.log('非全局:','eareeae ea'.match(/(ar)(e)/))// ['are', 'ar', 'e', index: 1, input: 'eareeae ea', groups: undefined]
console.log('全局:','eareeae ea'.match(/(ar)(e)/g)) // ['are']

console.log('非全局:','eareeae ea'.match(/(ar)(e)(ea)/)) // ['areea', 'ar', 'e', 'ea', index: 1, input: 'eareeae ea', groups: undefined]
console.log('全局:','eareeae ea'.match(/(ar)(e)(ea)/g)) // ['areea']

console.log('非全局:','3abc4,5abc6'.match(/a(bc)/)) // ['abc', 'bc', index: 1, input: '3abc4,5abc6', groups: undefined]
console.log('全局:','3abc4,5abc6'.match(/a(bc)/g)) // ['abc', 'abc']

w3school给的解释:

match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g

  • 如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。

    • 如果没有找到任何匹配的文本, match() 将返回 null。
    • 否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。
  • 如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。

    • 若没有找到任何匹配的子串,则返回 null。
    • 如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。
console.log('exex-非全局:',(/\d+/).exec('t3abc4,58abc6')) // ['3', index: 1, input: 't3abc4,58abc6', groups: undefined]
console.log('exex-全局:',(/\d+/g).exec('t3abc4,58abc6')) // ['3', index: 1, input: 't3abc4,58abc6', groups: undefined]

console.log('exex-非全局:',(/a(bc)/).exec('t3abc4,58abc6')) // ['abc', 'bc', index: 2, input: 't3abc4,58abc6', groups: undefined]
console.log('exex-全局:',(/a(bc)/g).exec('t3abc4,58abc6')) // ['abc', 'bc', index: 2, input: 't3abc4,58abc6', groups: undefined]

在 exec中正则表达式 加 g与否的结果都一样,都只返回第一个匹配到的结果。

w3schoole 给的解释:

区别:
1.match是返回所有匹配的字符串合成的数组,但是正则表达式必须指定全局g属性才能返回所有匹配,不指定g属性则会返回一个只有一个元素的数组。
2.exec永远返回与第一个匹配相关的信息,其返回数组包括第一个匹配的字串,所有分组的反向引用。

const req = require.context('./modules',true,/\.js/)
let modules = []
req.keys().forEach(modulePath=>{
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+/,'$1')
  modules[moduleName] = req(modulePath).default
})

元字符(特殊字符)

code说明
.匹配除换行符以外的任意字符,只有一个字符例外。这个例外就是换行符 (\n)。例如: a.c 匹配 abc acc a8c 等。
\w匹配字母或数字或下划线或汉字。例如:a\wc 匹配: abc a6c a_c a中c 等
\s匹配任何空白字符,包括空格、制表符、换页符等等。例如:a\sc 匹配:a c
\d匹配数字。 a\dc 匹配:a8c a5c
\b匹配单词的开始或结束,也就是指单词和空格间的位置。例如: ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
^匹配字符串的开始,如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。例如:ea 匹配"eareeae ea"中的"ea ea ea " 而 ^ea 匹配只匹配"ea",因为^是字符串的开始,只匹配开始的一个ea。
$匹配字符串的结束,如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。例如:lo$ 匹配"hello"中的 lo ,无法匹配"helloab"中的lo

\b:就是\b的两侧必须有空格、开始或结束。

在这里插入代码片

反义字符

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

code说明
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

转义字符

如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.\*

/***
 * 转义字符
 * @type {RegExp}
 */
// 1.可以匹配任意字符
let reg1 = /^.+$/

// 2.加了转义字符'\',所以只能匹配'.'
let reg2 = /^\.+$/

// 在'[]'里面的话,不用加转义即可。
let reg3 = /^[.]+$/
console.log(reg1.test('.')) // true
console.log(reg1.test('abc123QQ》*&')) // true

console.log(reg2.test('.')) // true
console.log(reg2.test('a')) // false
console.log(reg2.test('abc123QQ》*&')) // false

console.log(reg3.test('.')) // true
console.log(reg3.test('abc123QQ》*&')) // false

注:
js字符串中的反斜杠也需要转义,入下:

let reg1 = /\(/
let reg2 = /\\/

console.log(reg1.test('(')) // true
console.log(reg2.test('\\')) // true
// console.log('\') // 报错的!
console.log('\\') // \
console.log('我\你') // 我你

判断是否在集合字符(即中括号内):

1.不在集合字符内,需要转义的:
^ $ . * + ? | \ / ( ) [ ] { } -
2.在集合字符内,需要转义的:
^ - [ ] \

所以:1.-使用的时候,在中间的时候,不生效;放在最后或者转义;
2..在组内的时候,没有转义符;
eg:let reg = /^[\u4e00-\u9fa5_?'#()\\.,&%@!a-zA-Z0-9-]+$/
参考:https://blog.csdn.net/weixin_44100002/article/details/114373990
https://blog.csdn.net/weixin_45242865/article/details/121540017

限定字符

code说明
*重复零次或更多次.例如,zo* 能匹配 “z” 以及 “zoo”
+重复一次或更多次.例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”
?重复零次或一次. 例如‘di?’ 能匹配’di’以及’did’
{n}重复n次. ‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o
{n ,}重复n次或更多次. 例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等价于 ‘o+’。‘o{0,}’ 则等价于 ‘o*’。
{n,m}重复n到m次. m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。
/**
 * 限定符使用
 */
let reg1 = /di?/
let reg2 = /di?/g
console.log(reg1.test('di')) // true
console.log(reg1.test('did')) // true
console.log(reg1.test('diid')) // true
console.log('diid'.match(reg2)) // ['di', 'd']

普通字符

如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?

很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。

我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。

下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}

解析:
开头(,可以有,也可以没有(0次或者1次);然后0,然后两位数字;然后) 空格 或者-,可以有,可以没有;然后8位数字。

集合字符:[ ]

分支字符:|

如果满足其中任意一种规则都应该当成匹配,具体方法是用 | 把不同的规则分隔开。如果满足了某个分枝的话,就不会去再管其它的条件了。

0\d{2}-\d{8}|0\d{3}-\d{7}

分组字符:()

重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了

(\d{1,3}\.){3}\d{1,3}

(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})

参考:
https://blog.csdn.net/weixin_53299145/article/details/121779900

https://blog.csdn.net/xuemoyao/article/details/8033138

常用正则表达式:
https://blog.csdn.net/l1028386804/article/details/116778918
https://blog.csdn.net/ZYC88888/article/details/98479629
https://blog.csdn.net/liuhangbiao/article/details/113641127

var str = "col9*4+col10*col11/col12-col12"

str.split(/[+\-*/]/) //  ['col9', '4', 'col10', 'col11', 'col12', 'col12']

str.split(/[^+*/-]/) // ['col9', '4', 'col10', 'col11', 'col12', 'col12']

注:
1.在[]里面,其他的特殊字符不需要转义;
2. -在中间的时候,需要转义;在末尾不需要转义;
3. split方法的参数:string.split(separator,limit)

separator 可选。字符串或正则表达式。
limit 可选。该参数可指定返回的数组的最大长度。

备选字符集 []

6位数字做密码:

[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789]

[0123456789] 字符集中有且只能选择一个。
优化:

[0-9][0-9][0-9][0-9][0-9][0-9]

[a-z]–>1位小写字母

[A-Z]–>1位大写字母

[A-Za-z]–>1位字母,大小写都行

[0-9a-zA-Z]–>1位字母或数字都行

反选:[^不能选的字符列表]

比如:[^47]

注:^作“除了”使用时,只能放在开头

/[0-9][0-9][0-9][0-9][0-9][0-9]/.test(1234567) // true
/[0-9][0-9][0-9][0-9][0-9][0-9]/.test('1234567') // true
/[0-9]{6}/.test(1234567) // 1234567里面包含6位数字,所以true
/^[0-9]{6}$/.test(1234567) // false,六位数字开头且结尾

预定义字符集

/\d/--> /[0-9]/–>1位数字

/\w/ --> /[0-9a-zA-Z_]/ --> 1位字母,数字或_

/\s/–>1 位空字符:匹配任何空白字符,包括空格、制表符、换页符等等。
/. /: 除换行回车外的任何一个字符,如:

“a.[0-9]”:表示一个字符串有一个"a"后面跟着一个任意字符和一个数字;
“^.{3}$”:表示有任意三个字符的字符串(长度为3个字符)

预定义字符的反义:预定义字符的大写形式都是小写的反义
\D---->1位非数字字符

\S------匹配任何非空白字符。等价于 [^\f\n\r\t\v]。

六位密码:/^\d{6}$/.test('123456')

数量词

确定数量:3种:

{n}–> 必须反复出现n位

{n,m}–> 最少出现n次,最多出现m次

{n,}–>至少出现n次,多了不限!

不确定数量:3种:

*: 有没有都行,次数不限,相当于{0,}

+: 至少1次,重复次数不限,相当于{1,}

?: 有没有都行,最多1次,相当于{0,1}

其他

():分组

|: 左右两正则表达式选其一

demo: 手机号规则: 第1位:只能是1,第2位:[34578],第3位之后,必须是9位数字。
身份证号逻辑: 前15位数字,16,17位必须是数字, 最后一位可以是数字或X x, 后三位 可有可无,如果有,只能出现一次
手机号:,手机号前可能出现+86或0086。, 前缀可有可无,且只能出现一次,前缀和手机号之间可以有或没有任意个空字符 ,第1位:只能是1,第2位:[34578], 第3位之后,必须是9位数字

手机号:/^1[34578]\d{9}$/
身份证:/\d{15}(\d\d[X|x|\d])?/ ==> /^\d{15}(\d\d[Xx\d])?$/

/(^\d{15})|(^\d{17}[Xx\d])/
/(^\d{15})$|(^\d{17}(x|X|\d))$/
手机号:/^((\+86)|(0086))?\s?1[34578]\d{9}$/

指定匹配位置:

^表达式: 必须以表达式的规则为开头

表达式$: 必须以表达式的规则为结尾

预判

1)(?=表达式): 先浏览字符串是否满足表达式的要求
2)(?!表达式):先检查字符串是否不满足表达式要求

特殊字符

下面列出了正则表达式中的特殊字符:(请注意在方括号中,不需要转义字符。)

“$”------匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 $。

“()”----标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。

“*”----匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。

“+”-----匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。

“.”----匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 .。

“[”------标记一个中括号表达式的开始。要匹配 [,请使用 [。

“?”----匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。

“\”----将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。‘\n’ 匹配换行符。序列 ‘\’ 匹配 “”,而 ‘(’ 则匹配 “(”.

“^”-----匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 ^。

“{”----标记限定符表达式的开始。要匹配 {,请使用 {。

“|”----指明两项之间的一个选择。要匹配 |,请使用 |。

参考:https://www.cnblogs.com/crystaltu/p/5883955.html

中文符号

背景:不能输入中文字符 和 中文符号
中文字符有集合,符号怎么办?

function checkText() {
 var text = ",";
 //匹配这些中文标点符号 。 ? ! , 、 ; : “ ” ‘ ' ( ) 《 》 〈 〉 【 】 『 』 「 」 ﹃ ﹄ 〔 〕 … — ~ ﹏ ¥
 var reg = /[\u3002|\uff1f|\uff01|\uff0c|\u3001|\uff1b|\uff1a|\u201c|\u201d|\u2018|\u2019|\uff08|\uff09|\u300a|\u300b|\u3008|\u3009|\u3010|\u3011|\u300e|\u300f|\u300c|\u300d|\ufe43|\ufe44|\u3014|\u3015|\u2026|\u2014|\uff5e|\ufe4f|\uffe5]/;
 if(reg.test(text)){
  alert('是中文标点符号');
 }else{
  alert('不是中文标点符号');
 }
}

使用\s来匹配任意空白字符,包括空格、制表符、换行符等。

// 中文正则
\u4e00-\u9fa5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值