常见正则问题


正则

问题:
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


版权声明:本文为weixin_42995876原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。