javascript - Javascript RegExp 用于精确匹配具有特殊字符的多个单词
问题描述
我正在使用 RegExp 进行多个单词匹配。它具有动态值,因此当出现像“(”这样的特殊字符时,它会将其作为表达式并显示 Uncaught SyntaxError: Invalid regular expression 错误。
let text = 'working text and (not working text'
let findTerm = ['working text', '(not working text']
let replaceFromRegExp = new RegExp('\\b'+`(${findTerm.join("|")})`+'\\b', 'g')
text = text.replace(replaceFromRegExp, match => "<mark>" + match + "</mark>")
console.log(text)
解决方案
\b
单词边界匹配以下三个位置中的任何一个:
- 在字符串的第一个字符之前,如果第一个字符是单词字符。
- 在字符串的最后一个字符之后,如果最后一个字符是单词字符。
- 在字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。您需要通用单词边界,在搜索词之前需要一个非单词字符或字符串开头,在搜索字符串之后需要一个非单词字符或字符串结尾。
请注意,您还需要findTerm
按长度按降序对项目进行排序,以避免重叠术语问题。
最后,不要忘记转义findTerm
要在正则表达式模式中使用的项目。
您可以使用
let text = 'working text and (not working text'
let findTerm = ['working text', '(not working text']
findTerm.sort((a, b) => b.length - a.length);
let replaceFromRegExp = new RegExp(String.raw`(?:\B(?!\w)|\b(?=\w))(?:${findTerm.map(x => x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join("|")})(?:(?<=\w)\b|(?<!\w)\B)`, 'g')
// If the boundaries for special chars should not be checked remove \B:
// let replaceFromRegExp = new RegExp(String.raw`(?:(?!\w)|\b(?=\w))(?:${findTerm.map(x => x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join("|")})(?:(?<=\w)\b|(?<!\w))`, 'g')
console.log(replaceFromRegExp)
text = text.replace(replaceFromRegExp, "<mark>$&</mark>")
console.log(text)
请注意,这"<mark>$&</mark>"
是一种更简短的说法match => "<mark>" + match + "</mark>"
,就像$&
在字符串替换模式中对整个匹配值的反向引用一样。
正则表达式是
/(?:\B(?!\w)|\b(?=\w))(?:\(not working text|working text)(?:(?<=\w)\b|(?<!\w)\B)/g
或者
/(?:(?!\w)|\b(?=\w))(?:\(not working text|working text)(?:(?<=\w)\b|(?<!\w))/g
请参阅正则表达式 #1 演示和正则表达式 #2 演示。详情:
(?:\B(?!\w)|\b(?=\w))
- 如果下一个字符不是单词字符,则为非单词边界;如果下一个字符为单词字符,则为单词边界(?:(?!\w)|\b(?=\w))
- 要么下一个 char 必须是非单词 char,要么在当前位置的左边必须没有单词 char,并且下一个必须是单词 char(如果术语以特殊 char 开头,则没有边界是必须的)(?:\(not working text|working text)
findTerm
- 与数组中设置的替代模式之一匹配的非捕获组(?:(?<=\w)\b|(?<!\w)\B)
- 如果前面的 char 是单词 char,则为单词边界;如果前面的 char 不是单词 char,则为非单词边界(?:(?<=\w)\b|(?<!\w))
- 如果前一个 char 是 word char,则下一个不能是 word char,或者前一个 char 不应该是 word char(如果 term 以特殊 char 结尾,则不需要边界)
推荐阅读
- java - 无法使用 objectmapper 从 html 字符串中读取值
- python - 误分类率和总误差不下降——神经网络调试
- javascript - JavaScript 字符串文字重用组件
- python - 使用 Python 的 Microsoft Sharepoint 身份验证
- spring-boot - 在 jwt 授权中获取问题 authenticationProvider
- mysql - MySQL 8 - 触发 INSERT - VCS 的重复 AUTO_INCREMENT id
- jquery - 选择多个传单标记并生成下载链接
- angular - S3 托管的 Angular 应用、Route53 和基于查询字符串的自定义
- scala - 有没有办法将具有多个小数点的字符串转换为 Scala 中的双精度值?
- mysql - 当数据可以出现在一个表的多个列中时,连接两个表的结果