The answer from CertainPerformance 更好 - 更易于实现和维护,但值得注意的是 - 您还可以从数组生成正则表达式。
这个想法很简单——如果你想匹配r、re、rea、read、readi、readin、reading,那么正则表达式就是reading|readin|readi|read|rea|re|r。您首先需要最长变化的原因是因为否则正则表达式引擎将在 finds 中的第一个匹配项处停止:
let regex = /r|re|rea|read/g
// ↑_________________
console.log( // |
"read".replace(regex, "")// |
// ↑___________________________|
)
所以你可以把一个词分解成这种模式来生成一个正则表达式
function allSubstrings(word) {
let substrings = [];
for (let i = word.length; i > 0; i--) {
let sub = word.slice(0, i);
substrings.push(sub)
}
return substrings;
}
console.log(allSubstrings("reading"))
这样您就可以简单地生成所需的正则表达式。
function allSubstrings(word) {
let substrings = [];
for (let i = word.length; i > 0; i--) {
let sub = word.slice(0, i);
substrings.push(sub)
}
return substrings;
}
function toPattern(word) {
let substrings = allSubstrings(word);
let pattern = substrings.join("|");
return pattern;
}
console.log(toPattern("reading"))
最后是获取一个数组并将其转换为正则表达式。这需要处理每个单词,然后将每个单独的正则表达式组合成一个匹配任何单词的正则表达式:
const array = ['reading', 'books'];
const string = 'If you want to read the book, just read it.';
//generate the pattern
let pattern = array
.map(toPattern) //first, for each word
.join("|"); //join patterns for all words
//convert the pattern to a regex
let regex = new RegExp(pattern, "g");
let result = string.replace(regex, "");
//desiredOutput: 'If you want to the , just it.';
console.log(result);
function allSubstrings(word) {
let substrings = [];
for (let i = word.length; i > 0; i--) {
let sub = word.slice(0, i);
substrings.push(sub)
}
return substrings;
}
function toPattern(word) {
let substrings = allSubstrings(word);
let pattern = substrings.join("|");
return pattern;
}
所以,这是如何您可以从该数组生成正则表达式。在 this 的情况下,这是可行的,但不能保证,因为它可能会匹配你不想要的东西。例如,r 将匹配 any 字符,它不一定需要在与之匹配的单词中。
const array = ['reading'];
const string = 'The quick brown fox jumps over the lazy dog';
// ^ ^
let pattern = array
.map(word => allSubstrings(word).join("|"))
.join("|");
let regex = new RegExp(pattern, "g");
let result = string.replace(regex, "");
console.log(result);
function allSubstrings(word) {
let substrings = [];
for (let i = word.length; i > 0; i--) {
let sub = word.slice(0, i);
substrings.push(sub)
}
return substrings;
}
这会变得更复杂,因为您想为每个单词生成更复杂的模式。您通常希望匹配单词,因此您可以使用单词边界字符\b,这意味着“阅读”的模式现在可以如下所示:
\breading\b|\breadin\b|\breadi\b|\bread\b|\brea\b|\bre\b|\br\b
↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑ ↑↑
为了保持输出至少有点可读性,可以将其放在一个组中,然后将整个组匹配一个单词:
\b(?:reading|readin|readi|read|rea|re|r)\b
↑↑
||____ non-capturing group
所以,你必须生成这个模式
function toPattern(word) {
let substrings = allSubstrings(word);
//escape backslashes, because this is a string literal and we need \b as content
let pattern = "\\b(?:" + substrings.join("|") + ")\\b";
return pattern;
}
这导致我们这样做
const array = ['reading', 'books'];
const string = 'The quick brown fox jumps over the lazy dog. If you want to read the book, just read it.';
let pattern = array
.map(toPattern)
.join("|");
let regex = new RegExp(pattern, "g");
let result = string.replace(regex, "");
console.log(result);
function allSubstrings(word) {
let substrings = [];
for (let i = word.length; i > 0; i--) {
let sub = word.slice(0, i);
substrings.push(sub)
}
return substrings;
}
function toPattern(word) {
let substrings = allSubstrings(word);
let pattern = "\\b(?:" + substrings.join("|") + ")\\b";
return pattern;
}
这足以解决您的任务。所以生成一个正则表达式是可能的。最后一个看起来像这样:
/\b(?:reading|readin|readi|read|rea|re|r)\b|\b(?:books|book|boo|bo|b)\b/g
但它的大部分生成都花在尝试生成有效的东西。这不一定是一个复杂的解决方案,但如前所述,CertainPerformance 建议的解决方案更好,因为它更简单,这意味着它失败的可能性更小,并且将来更容易维护。