Storage存储-正则表达式(coderwhy版本)(一)https://developer.aliyun.com/article/1470355
match方法
使用字符串的方法,传入一个正则表达式
match(英文意思:匹配):找到匹配的数据(如果要全部的数据,修饰符中就加上g,也就是全局的意思)
const message = "fdabc fa44BC df5ABC AaaBc66" const re1 = /abc/ig const re2 = message.match(re1) console.log(re2)
matchAll方法
跟用修饰符g返回的结果有什么不一样?这个返回的是一个迭代器
使用matchAll方法前提:正则修饰符必须加g(因为All的前置条件就是能够全局查找)
const message = "fdabc fa44BC df5ABC AaaBc66" const re1 = /abc/ig const re2 = message.matchAll(re1) console.log(re2) console.log(re2.next()) console.log(re2.next()) console.log(re2.next())
//当然迭代器必不可免能够用到的当然是遍历了 const message = "fdabc fa44BC df5ABC AaaBc66" const re1 = /abc/ig const re2 = message.matchAll(re1) for(item of re2){ console.log(item) }
replace/replaceAll方法
在前面用过
split方法
一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法
const message = "fdabc fa44BC df5ABC AaaBc66" const re1 = /abc/ig const result4 = message.split(re1) console.log(result4)
search方法
返回第一个符合条件的索引,没有搜索到返回-1
const message = "fdabc fa44BC df5ABC AaaBc66" const re1 = /abc/ig const result5 = message.search(re1) console.log(result5)//2
(理解)正则-正则表达式规则-字符类和反向类
修饰符flag的使用
- 常见的修饰符:
flag |
含义 |
g |
全部的,给我匹配全部的(global) |
i |
忽略大小写(ignore) |
m |
多行匹配(multiple) |
- 需求:
- 获取一个字符串中所有的abc;
- 将一个字符串中的所有abc换成大写
规则 – 字符类(Character classes)
- 字符类(Character classes) 是一个特殊的符号,匹配特定集中的任何符号
字符 |
含义 |
\d(“d” 来自 “digit”) |
数字:从 0 到 9 的字符 |
\s(“s” 来自 “space”) |
空格符号:包括空格,制表符 \t,换行符 \n 和其他少数稀有字符,例如 \v,\f 和 \r |
\w(“w” 来自 “word”) |
“单字”字符:拉丁字母或数字或下划线 _。 |
.(点) |
点 . 是一种特殊字符类,它与 “除换行符之外的任何字符” 匹配 |
- 反向类(Inverse classes)
- \D 非数字:除 \d 以外的任何字符,例如字母
- \S 非空格符号:除 \s 以外的任何字符,例如字母
- \W 非单字字符:除 \w 以外的任何字符,例如非拉丁字母或空格
(理解)正则-正则表达式规则-锚点和词边界
规则 – 锚点(Anchors)
- 符号 ^ 和符号 $ 在正则表达式中具有特殊的意义,它们被称为“锚点”。
- 符号 ^ 匹配文本开头
- 符号 $ 匹配文本末尾
//以前字符串的方法 const message = "my name is xiaoyu" if(message.startWith("my")){ console.log("以my开头") } if(message.endWith("why")){ console.log("以my结尾") } //正则的方法 if(/^my/i.test(message)){ console.log("以my开头") } if(/my$/i.test(message)){ console.log("以my结尾") } //如果^XXX$,则必须完全符合
- 词边界(Word boundary)
- 词边界 \b 是一种检查,就像 ^ 和 $ 一样,它会检查字符串中的位置是否是词边界
- 词边界测试 \b 检查位置的一侧是否匹配 \w,而另一侧则不匹配 “\w”
const message = "My name is xiaoyu" //需求:name必须是一个单独的词,中间没有\w之类的东西 //词边界 if(/\bname\b/i.test(message)){//依靠/b XXX \b,进行划分边界 console.log("有name") }
- 在字符串 Hello, Java! 中,以下位置对应于 \b:
- 匹配下面字符串中的时间:
//词边界应用 const infos = "now time is 11:56 number is 123:456" const timeRe = /\b\d\d:\d\d\b/ig //边界 \0-9\0-9:\0-9\0-9 边界/不区分带小写、全局查找 console.log(infos.match(timeRe))
(理解)正则-正则表达式规则-转义字符
规则 – 转义字符串
- 如果要把特殊字符作为常规字符来使用,需要对其进行转义:
- 只需要在它前面加个反斜杠;
- 常见的需要转义的字符:
- **[] \ ^ $ . | ? + ( )
- 斜杠符号 ‘/’ 并不是一个特殊符号,但是在字面量正则表达式中也需要转义;
- 练习:匹配所有以.js或者jsx结尾的文件名
//词边界应用 const fileNames = ["node.js","three.js","Vue.js","React.js","luo.go","xiaoman.java","home.jsx"] const jsfileRe = /\.jsx?$/i//匹配规则 ///\.jsx?$/ 这里的x?表示x是0个或者1个 const newFileNames = []//创建空数组用来存放 for(const filename of fileNames){ if(jsfileRe.test(filename)){//找出所有符合条件的,防止不符合条件的打印出来undefined newFileNames.push(filename)//符合的填入数组 } } console.log(newFileNames);//['node.js', 'three.js', 'Vue.js', 'React.js', 'home.jsx']
//优化for循环 const fileNames = ["node.js","three.js","Vue.js","React.js","luo.go","xiaoman.java","home.jsx"] const jsfileRe = /\.jsx?$/i//匹配规则 //filter高阶函数 const newFileNames = fileNames.filter(fileName=>jsfileRe.test(fileName)) console.log(newFileNames)//['node.js', 'three.js', 'Vue.js', 'React.js', 'home.jsx']
- 在webpack当中,匹配文件名时就是以这样的方式。
(理解)正则-正则表达式规则-集合和范围
集合(Sets)和范围(Ranges)
- 有时候我们只要选择多个匹配字符的其中之一就可以:
- 在方括号 […] 中的几个字符或者字符类意味着“搜索给定的字符中的任意一个”;
- 集合(Sets)
- 比如说,[eao] 意味着查找在 3 个字符 ‘a’、‘e’ 或者 `‘o’ 中的任意一个;
- 范围(Ranges)
- 方括号也可以包含字符范围
- 比如说,[a-z] 会匹配从 a 到 z 范围内的字母,[0-5] 表示从 0 到 5 的数字
- [0-9A-F] 表示两个范围:它搜索一个字符,满足数字 0 到 9 或字母 A 到 F
- \d —— 和 [0-9] 相同
- \w —— 和 [a-zA-Z0-9_] 相同
- 案例:匹配手机号码:第一位是1,第二位是3、5、6、7、8、9其中之一,加上后面9位[0-9]的数字一共11位数,最后第11位就$结尾,不能再添加其他数字
- 排除范围:除了普通的范围匹配,还有类似 [^…] 的“排除”范围匹配
(理解)正则-正则表达式规则-量词用法
量词(Quantifiers)
- 假设我们有一个字符串 +7(903)-123-45-67,并且想要找到它包含的所有数字
- 因为它们的数量是不同的,所以我们需要给与数量一个范围
- 用来形容我们所需要的数量的词被称为量词( Quantifiers )
- 数量 {n}
- 确切的位数:{5}
- 某个范围的位数:{3,5} 这里逗号后面不能加空格
- 缩写:
- +:代表“一个或多个”,相当于 {1,}
- ?:代表“零个或一个”,相当于 {0,1}。换句话说,它使得符号变得可选
- *:代表着“零个或多个”,相当于 {0,}。也就是说,这个字符可以多次出现或不出现
- 案例:匹配开始或结束标签,字符串的html元素
开头/是特殊情况需要前面加\,然后?是因为如果不加就意味着这里开头就必须要有a-z其中一个字母,需要考虑下边界效应
(理解)正则-正则表达式规则-贪婪和惰性模式
贪婪( Greedy)和惰性( lazy)模式
- 如果我们有这样一个需求:匹配下面字符串中所有使用《》包裹的内容
const message = "我喜欢的一些书:《龙族》-《Vue.js设计与实现》-《沙哈拉的沙漠》-《许三观卖血记》" const result = message.match(/《.+》/g)//``.+`的意思是匹配任意内容,内容至少1个,不能无内容 console.log(result)//会打印出来['《龙族》-《Vue.js设计与实现》-《沙哈拉的沙漠》-《许三观卖血记》'],把所有的内容都连着一起打印出来了,这就是贪婪模式,找到的是龙族前面的《 跟许三观卖血记后面的》
- 默认情况下的匹配规则是查找到匹配的内容后,会继续向后查找,一直找到最后一个匹配的内容
- 这种匹配的方式,我们称之为贪婪模式(Greedy)
- 懒惰模式中的量词与贪婪模式中的是相反的。(使用频率更高)
- 只要获取到对应的内容后,就不再继续向后匹配;
- 我们可以在量词后面再加一个问号 ‘?’ 来启用它;
- 所以匹配模式变为 *? 或 +?,甚至将 '?' 变为 ??
//也就是/《.+》/g变成/《.+?》/g,就是开启了惰性模式,在+后面加上问号 const message = "我喜欢的一些书:《龙族》-《Vue.js设计与实现》-《沙哈拉的沙漠》-《许三观卖血记》" const result = message.match(/《.+?》/g)//``.+`的意思是匹配任意内容,内容至少1个,不能无内容 console.log(result)//会打印出来['《龙族》', '《Vue.js设计与实现》', '《沙哈拉的沙漠》', '《许三观卖血记》'] //惰性的会进行书名分开,而不是一口气全部输出了
(理解)正则-正则表达式规则-捕获器和或操作
捕获组(capturing group)
- 模式的一部分可以用括号括起来 (...),这称为“捕获组(capturing group)”
- 这有两个作用:
- 它允许将匹配的一部分作为结果数组中的单独项
- 它将括号视为一个整体;
- 方法 str.match(regexp),如果 regexp 没有 g 标志,将查找第一个匹配并将它作为一个数组返回:
- 在索引 0 处:完全匹配。
- 在索引 1 处:第一个括号的内容
- 在索引 2 处:第二个括号的内容
- …等等…
const message = "我喜欢的一些书:《龙族》-《Vue.js设计与实现》-《沙哈拉的沙漠》-《许三观卖血记》" const result = message.matchAll(/《(.+?)》/g)//``.+`的意思是匹配任意内容,内容至少1个,不能无内容 for(item of result){ console.log(item); } //第一波使用捕获组
//就能做出如下操作 const message = "我喜欢的一些书:《龙族》-《Vue.js设计与实现》-《沙哈拉的沙漠》-《许三观卖血记》" const result = message.matchAll(/《(.+?)》/g)//用括号 括起来,多个括号里的内容会分别排列在索引上 for(item of result){ console.log(item[1]);//取出索引 }
- 案例:匹配到HTML标签,并且获取其中的内容
捕获组的补充
- 命名组:
- 用数字记录组很困难。
- 对于更复杂的模式,计算括号很不方便。我们有一个更好的选择:给括号起个名字。
- 这是通过在开始括号之后立即放置 ? 来完成的
- 非捕获组:
- 有时我们需要括号才能正确应用量词,但我们不希望它们的内容出现在结果中。
- 可以通过在开头添加 ?: 来排除组
- or是正则表达式中的一个术语,实际上是一个简单的“或”。
- 在正则表达式中,它用竖线 | 表示;
- 通常会和捕获组一起来使用,在其中表示多个值;
const abcRe = /(abc|cba|nba){2,}/ //{2,}表示前面的表达式匹配的次数必须是2次或更多次。例如,正则表达式/(abc|cba|nba){2,}/匹配连续出现2次或更多次的"abc"、"cba"或"nba"。例如,它将匹配"abccba"、"nbanba"、"cbacbanba",但不匹配"abc"、"cba"或"nba"