我试图通过使用正则表达式范围来避免数组和循环,但是,我只想替换范围中每个字符的第一个实例。
我使用范围是因为我无法保证订单,也无法重新订购。
例如:
"access".replace(/[access]/g, '') = "cs", instead of "".
"cell phones".replace(/[el]/g) = "cl phones", instead of "c phons"
正则表达式范围内的双打无论如何都是多余的,在这种情况下,它也不应该导致第二次出现被替换。
如果这是不可能的,那么我将不得不考虑别的事情。
答案 0 :(得分:2)
这需要一个后视 - 查看角色是否已经发生过,因此应该保留。但JS并不支持这一点。搜索" JS look-behind regexp"一些想法。经典的方法是反转字符串,以便您可以使用预测:
const rev = s => s.split('').reverse().join('');
const testData = [
["access", 'access'],
["cell phones", 'el']
];
function match(s, chrs) {
const reg = new RegExp(`([${chrs}])(?!.*\\1)`, "g");
return rev(rev(s).replace(reg, ''));
}
testData.forEach(([input, chrs]) => console.log("input", input, "gives", match(input, chrs)));

答案 1 :(得分:0)
作为我在上述评论中所说的例子:
function replace(str, regex) {
var cache = {}; // the cache object
return str.replace(regex, function(m) {
if(cache[m]) return m; // if we already removed an instance of this matched character then don't remove any further instances
// otherwise ...
cache[m] = true; // cache the character
return ''; // remove it
});
}
console.log('"access", /[access]/g => ', replace("access", /[access]/g));
console.log('"cell phones", /[el]/g => ', replace("cell phones", /[el]/g));

注意:假设传递的正则表达式都只是字符集(您调用它们的范围),只允许/[...]/g
,或者行为不会被取消你想要什么。
答案 2 :(得分:0)
“记住”逻辑的单行版本。
"cell phones".replace(/[el]/g, (() => { let seen = []; return m => seen.includes(m) ? m : (seen.push(m),''); })())
较短的版本:
"cell phones".replace(/[el]/g, (seen => m => m in seen ? m : seen[m] = ''))({}))