正则表达式 /s
正则表达式(Regular Expression)简称为正则,是一个通用的文本模式匹配工具。通过重复百度、Chrome和VSCode的文档,我对正则表达式的掌握还是有一定的了解和经验的。今天,我们来详细学习一下/s修饰符。
/s修饰符是什么?
/s是一个正则表达式修饰符,又称为DOTALL模式。正常情况下,用’.’来匹配字符,但在/s模式下,’.’可以匹配任何字符(包括换行符 ‘\n’),从而解决了跨行匹配的问题。在不使用/s修饰符的情况下,’.’将无法匹配换行符。下面提供一个例子。
const str = 'Hello\nworld!';
console.log(/world/.test(str)); // false
console.log(/world/s.test(str)); // true
其中,str字符串中包含一个换行符,且我们需要匹配world这个字符串。在不使用/s修饰符的情况下,’.’将无法跨行匹配word,所以第一行输出false。而在/s修饰符的情况下,’.’可以匹配所有字符,包括换行符,所以第二行输出true。
/s的应用场景
/s常用于匹配一段连续的文本,且文本间包含有换行。拿一个网页的html代码来说,很多时候想匹配一个块元素内容,每段内容中间用换行符分隔。
<div>
<p>Hello</p>
<p>world!</p>
</div>
如果要匹配这个整个div块,正则表达式可以简单写成:
const reg = /<div>.*<\/div>/s;
其中,’.*’表示匹配任意数量的字符,包括换行符’\n’。这样就可以匹配整个div块的内容了。
再列一个网页中的JS代码:
<script type="text/javascript">
function showMsg() {
console.log('Hello, world!');
}
</script>
如果要匹配其中的JS代码块,正则表达式可以写成:
/<script.*?>([\s\S]*)<\/script>/s
其中,’[\s\S]*’表示匹配空白符(’ ‘ ‘\t’ ‘\f’ ‘\r’ 或 ‘\n’)或非空白符的字符串,’/?’表示非贪婪匹配,括号内的内容就是匹配到的JS代码块。
组合修饰符
除了/s修饰符外,正则表达式中还有很多修饰符,如g、i、m等。有时候需要组合多个修饰符进行使用来满足不同的匹配需求。在组合修饰符时,可以使用|来连接。
比如,常用的/s和/i可以组合使用:
const str = 'HELLO\nworld!';
console.log(/hello.*world/i.test(str)); // true
console.log(/hello.*world/is.test(str)); // true
上面两行代码写的是不同的正则表达式,中间使用’/’分隔。第一行使用了/i修饰符,表示忽略大小写,可以匹配Hello和world。第二行中,使用了is两个修饰符,其中/s匹配了跨行字符,/i忽略了大小写,所以依然可以正确地匹配。
一些坑点
使用/s修饰符可能会遇到不少坑点,这里列举一下常见的几个。
- 不兼容IE在IE浏览器中,不支持使用/s修饰符,所以需要特别注意。建议在使用/s修饰符前,先判断一下浏览器是否支持该修饰符,如下:
const isIE = navigator.userAgent.indexOf('Trident') !== -1;
const reg = new RegExp('hello.*world', isIE ? 'i' : 'is');
这里使用navigator.userAgent来判断是否是IE浏览器,如果是,则使用’i’修饰符(即不区分大小写),否则使用is修饰符(即跨行匹配、不区分大小写)。
- 性能问题
使用/s修饰符可能会对性能产生影响,因为要匹配任意字符,包括换行符等。如果使用不当,会导致匹配时间过长,影响页面加载速度和用户体验。在使用/s修饰符时,尽量使用懒惰匹配,避免过度的匹配。比如,’.?’会比’.’更快,只匹配必要的字符。
- 嵌套问题
在使用/s修饰符时,也有嵌套的问题。如果一个字符串中包含两个相同的标签嵌套,正则表达式会匹配整个结构。这时可以使用嵌套匹配的方式,如:
const str = '<div><p>Hello</p></div>world!</div>';
const reg = /<div>((?:.|\n)*?)<\/div>/s;
console.log(reg.exec(str));
其中,(?:.|\n)表示非捕获组,(?:.|\n)*?表示尽可能少的匹配任意字符,直到遇到'<\/div>’为止。
结论
/s修饰符是一个很有用的正则表达式修饰符,可以解决跨行匹配问题。但在使用时,需要注意上面提到的一些问题,以免造成意外的结果和性能问题。