I am given two variables, a string [var str] and an array of words [var exceptions]. I am replacing every middle character of every word longer than 3 letters with an asterisk using the following regular expression:
我有两个变量,一个字符串[var str]和一个单词数组[var exception]。我正在用一个星号替换每一个超过3个字母的中间字符,使用以下正则表达式:
var edited = str.replace(/\B\w\B/g, '*');
For example, the string "This is an example of what I am doing" would be returned as "T**s is an e*****e of w**t I am d***g".
例如,字符串“这是我正在做的一个示例”将被返回为“T**s是w** T I am d***g的e**** e”。
However, I would like to add exceptions to this regular expression. So for example, I am given the array (var exceptions = ["example","doing"]
), then I would like the regex to return: "T**s is an example of w**t I am doing"
但是,我想对这个正则表达式添加异常。例如,我得到了数组(var exception = ["example","doing"),然后我希望regex返回:"T**s是我正在做的w* T的一个例子"
Does anyone know how to do this? If there is a way to achieve this using regex great, if not I am open to other suggestions.
有人知道怎么做吗?如果有一种方法可以使用regex great实现这一点,如果没有,我可以接受其他建议。
Many thanks :)
非常感谢:)
4 个解决方案
#1
1
I'd probably turn the array of excludes into a map so that I benefit from faster checking if a word is in the array. Then I'd use the fact that the replace
function accepts a function for the replacement, and make the decision in there:
我可能会将排除的数组转换为映射,以便更快地检查数组中是否有单词。然后我将使用替换函数接受替换函数的事实,并在其中做出决定:
var exclude = ["example", "what"];
var str = "This is an example of what I am doing";
var map = Object.create(null);
exclude.forEach(function(entry) {
map[entry] = true;
});
var edited = str.replace(/\b(\w)(\w+)(\w)\b/g, function(m, c0, c1, c2) {
return map[m] ? m : c0 + "*".repeat(c1.length) + c2;
});
console.log(edited);
I've used String#repeat
in the above, which is from ES2015, but can be easily shimmed for older browsers. Or use c1.replace(/./g, "*")
instead.
我在上面使用了字符串#repeat,它来自ES2015,但是对于老版本的浏览器来说,可以很容易地实现。或使用c1.replace(/。/ g,“*”)。
Here's an ES2015+ version, using Set
rather than an object map:
下面是ES2015+版本,使用Set而不是对象映射:
let exclude = ["example", "what"];
let str = "This is an example of what I am doing";
let set = new Set();
exclude.forEach(entry => {
set.add(entry);
});
let edited = str.replace(/\b(\w)(\w+)(\w)\b/g, (m, c0, c1, c2) =>
set.has(m) ? m : c0 + "*".repeat(c1.length) + c2
);
console.log(edited);
#2
2
You may use the exception words - I see they all consist of word chars - as an alternation group and capture it into Group 1 and then restore them inside a replace
callback.
您可以使用异常词——我看到它们都由单词chars组成——作为一个交替组,将其捕获到组1中,然后在replace回调中恢复它们。
The regex will look like
regex将看起来像
/\b(example|doing)\b|\B\w\B/g
See the JS demo:
看到JS演示:
var exceptions = ["example","doing"];
var rx = new RegExp("\\b(" + exceptions.join("|") + ")\\b|\\B\\w\\B", "g");
var s = "This is an example of what I am doing";
var res = s.replace(rx, function ($0, $1) {
return $1 ? $1 : '*';
});
console.log(res);
Pattern details:
模式的细节:
-
\b(example|doing)\b
- match a whole wordexample
ordoing
and place into capturing group #1 to be restores in the result later - \b(示例|doing)\b—匹配一个完整的单词示例或doing,并将其放置到捕获组#1中,以便稍后在结果中恢复
-
|
- or - |——或者
-
\B\w\B
- match a word char inside other word chars (from[a-zA-Z0-9_]
set). - \B\w\B -在其他单词chars中匹配一个单词char(来自[a- za - z0 -9_] set)。
#3
1
Split the sentence in separate words with .split(" ")
. Then for each word, check if it is in the array of exceptions, if it is not, just add it to the newString without changes. If it is not, apply your regex.
用. Split(")把这个句子分成几个单词。然后,对于每个单词,检查它是否在异常数组中,如果不是,只需将它添加到newString中,不做任何更改。如果不是,应用您的regex。
var newString = "";
var exceptions = ["test"];
"this is a test".split(" ").forEach(word =>{
if(exceptions.includes(word))
newString += word + " ";
else
newString += word.replace(/\B\w\B/g, '*') + " ";
});
console.log(newString)
#4
1
You could do it this way, assuming that words are always separated by spaces exclusively:
你可以这样做,假设单词总是被单独的空格隔开:
var str = "This is an example of what I am doing";
var exceptions = [ "example", "doing" ];
var edited = str.split(' ').map(function(w) {
return exceptions.indexOf(w) != -1 ? w : w.replace(/\B\w\B/g, '*');
}).join(' ');
console.log(edited);
#1
1
I'd probably turn the array of excludes into a map so that I benefit from faster checking if a word is in the array. Then I'd use the fact that the replace
function accepts a function for the replacement, and make the decision in there:
我可能会将排除的数组转换为映射,以便更快地检查数组中是否有单词。然后我将使用替换函数接受替换函数的事实,并在其中做出决定:
var exclude = ["example", "what"];
var str = "This is an example of what I am doing";
var map = Object.create(null);
exclude.forEach(function(entry) {
map[entry] = true;
});
var edited = str.replace(/\b(\w)(\w+)(\w)\b/g, function(m, c0, c1, c2) {
return map[m] ? m : c0 + "*".repeat(c1.length) + c2;
});
console.log(edited);
I've used String#repeat
in the above, which is from ES2015, but can be easily shimmed for older browsers. Or use c1.replace(/./g, "*")
instead.
我在上面使用了字符串#repeat,它来自ES2015,但是对于老版本的浏览器来说,可以很容易地实现。或使用c1.replace(/。/ g,“*”)。
Here's an ES2015+ version, using Set
rather than an object map:
下面是ES2015+版本,使用Set而不是对象映射:
let exclude = ["example", "what"];
let str = "This is an example of what I am doing";
let set = new Set();
exclude.forEach(entry => {
set.add(entry);
});
let edited = str.replace(/\b(\w)(\w+)(\w)\b/g, (m, c0, c1, c2) =>
set.has(m) ? m : c0 + "*".repeat(c1.length) + c2
);
console.log(edited);
#2
2
You may use the exception words - I see they all consist of word chars - as an alternation group and capture it into Group 1 and then restore them inside a replace
callback.
您可以使用异常词——我看到它们都由单词chars组成——作为一个交替组,将其捕获到组1中,然后在replace回调中恢复它们。
The regex will look like
regex将看起来像
/\b(example|doing)\b|\B\w\B/g
See the JS demo:
看到JS演示:
var exceptions = ["example","doing"];
var rx = new RegExp("\\b(" + exceptions.join("|") + ")\\b|\\B\\w\\B", "g");
var s = "This is an example of what I am doing";
var res = s.replace(rx, function ($0, $1) {
return $1 ? $1 : '*';
});
console.log(res);
Pattern details:
模式的细节:
-
\b(example|doing)\b
- match a whole wordexample
ordoing
and place into capturing group #1 to be restores in the result later - \b(示例|doing)\b—匹配一个完整的单词示例或doing,并将其放置到捕获组#1中,以便稍后在结果中恢复
-
|
- or - |——或者
-
\B\w\B
- match a word char inside other word chars (from[a-zA-Z0-9_]
set). - \B\w\B -在其他单词chars中匹配一个单词char(来自[a- za - z0 -9_] set)。
#3
1
Split the sentence in separate words with .split(" ")
. Then for each word, check if it is in the array of exceptions, if it is not, just add it to the newString without changes. If it is not, apply your regex.
用. Split(")把这个句子分成几个单词。然后,对于每个单词,检查它是否在异常数组中,如果不是,只需将它添加到newString中,不做任何更改。如果不是,应用您的regex。
var newString = "";
var exceptions = ["test"];
"this is a test".split(" ").forEach(word =>{
if(exceptions.includes(word))
newString += word + " ";
else
newString += word.replace(/\B\w\B/g, '*') + " ";
});
console.log(newString)
#4
1
You could do it this way, assuming that words are always separated by spaces exclusively:
你可以这样做,假设单词总是被单独的空格隔开:
var str = "This is an example of what I am doing";
var exceptions = [ "example", "doing" ];
var edited = str.split(' ').map(function(w) {
return exceptions.indexOf(w) != -1 ? w : w.replace(/\B\w\B/g, '*');
}).join(' ');
console.log(edited);