正则表达式中特殊字符的转义

4,132 阅读1分钟

前言

最近在工作中遇到了关于正则表达式特殊字符的问题,在某度搜索未果后,自己捣鼓了半天解决了,故写这篇文章出来进行总结,如果有任何地方有错误,欢迎在评论区交流。

遇到的问题

这个问题是利用正则表达式搜索关键字,但是如果关键字包含了特殊符号,会导致正则表达式报错无法执行,我们需要过滤一次关键字,把特殊符号转为转义后的字符再进行搜索。

须知

正则表达式中的特殊字符

  • $
  • ]
  • [
  • )
  • (
  • *
  • +
  • .
  • ?
  • \
  • ^
  • {
  • }

特殊符号为什么需要转义

特殊符号在正则表达式中,都有特殊的用途,直接使用并不能代表其原来的意思。
举个🌰 : x|y x和y的任意一方相同都会被认为一致。即"(z|f)ood""zood","food"都一致。 其他的符号这里不一一细说,有兴趣的可以看看这篇文章

既然特殊符号不能正常表示原来的意思,我们就需要对其进行转义,方法就是在对应符号前加\这个符号,可以使其代表原来的意思。

需要用到的API

String.prototype.replace()

replace()  方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。

至于replace()的用法本文不在细说,有兴趣的小伙伴可以点击上面的链接深入学习,接下来我们借助这个API来实现需要实现的功能。

场景

我们先看看没有特殊字符的场景

const str = "Fish eat shrimp"
function replace(str, keyword) {
    const regex = new RegExp(`(${keyword})`, "gi")
    console.log("regex", regex)  
    str = str.replace(regex, "老鱼")
    console.log("str", str)
}
replace(str, "Fish") 
replace(str, "shrimp") 

// 输出
// regex /(Fish)/gi
// str 老鱼 eat shrimp
// regex /(shrimp)/gi
// str Fish eat 老鱼

接下来我们看看有特殊字符的场景

const str = "[Fish eat shrimp)"
function replace(str, keyword) {
    const regex = new RegExp(`(${keyword})`, "gi")
    str = str.replace(regex, "老鱼")
    console.log("str", str)
}
replace(str, "[")
// 输出
// SyntaxError: Invalid regular expression: /([)/: Unterminated character class

可以看到,查询[符号的时候,正则表达式会直接报错,其他特殊符号在这里也是一样的情况,所以让我们来解决这个问题。

实现

这里就直接上代码了

const str = "[Fish eat shrimp)"

// 转义
function encode(keyword) {
    const reg = /[\[\(\$\^\.\]\*\\\?\+\{\}\\|\)]/gi
    return keyword.replace(reg, (key) => `\\${key}`)
}

function replace(str, keyword) {
    keyword = encode(keyword)
    console.log("keyword", keyword)
    const regex = new RegExp(`(${keyword})`, "gi")
    str = str.replace(regex, "老鱼")
    console.log("str", str)
}

replace(str, "[")
replace(str, "[Fish")

// 输出
// keyword \[
// str 老鱼Fish eat shrimp)
// keyword \[Fish
// str 老鱼 eat shrimp)

总结

function encode(keyword) {
    const reg = /[\[\(\$\^\.\]\*\\\?\+\{\}\\|\)]/gi
    return keyword.replace(reg, (key) => `\\${key}`)
}

这个函数可以转义正则表达式中需要正确使用的特殊字符。