Javascript Regex—;匹配范围,但每个唯一字符仅匹配一次
我试图通过使用正则表达式范围来避免数组和循环,但是,我只想替换范围中每个字符的第一个实例一次 我使用range是因为我不能保证订购,也不能重新订购 例如:Javascript Regex—;匹配范围,但每个唯一字符仅匹配一次,javascript,regex,regex-lookarounds,Javascript,Regex,Regex Lookarounds,我试图通过使用正则表达式范围来避免数组和循环,但是,我只想替换范围中每个字符的第一个实例一次 我使用range是因为我不能保证订购,也不能重新订购 例如: “access”。替换(/[access]/g',)=“cs”,而不是“”。 “手机”。替换(/[el]/g)=“cl手机”,而不是“c电话” 无论如何,正则表达式范围中的双精度是多余的,在本例中,它也不应导致替换第二个匹配项 如果这是不可能的,那么我将不得不考虑其他事情。这需要向后看一看——看看字符是否出现得更早,因此应该保留。但JS不支持
“access”。替换(/[access]/g',)=“cs”,而不是“”。
“手机”。替换(/[el]/g)=“cl手机”,而不是“c电话”
无论如何,正则表达式范围中的双精度是多余的,在本例中,它也不应导致替换第二个匹配项
如果这是不可能的,那么我将不得不考虑其他事情。这需要向后看一看——看看字符是否出现得更早,因此应该保留。但JS不支持这一点。搜索“jslookbehindregexp”获取一些想法。经典方法是反转字符串,以便使用look aheads:
const rev=s=>s.split(“”).reverse().join(“”);
常数testData=[
[“访问”,“访问”],
[“手机”,“el”]
];
功能匹配(s、chrs){
const reg=new RegExp(`([${chrs}])(?!**\\1)`,“g”);
返回版次(版次)。替换版次(版次,);
}
testData.forEach(([input,chrs])=>console.log(“input”,input,“gives”,match(input,chrs))代码>作为我在上面评论中所说的示例:
函数替换(str,regex){
var cache={};//缓存对象
返回str.replace(正则表达式,函数(m){
if(cache[m])返回m;//如果我们已经删除了此匹配字符的实例,则不删除任何其他实例
//否则。。。
cache[m]=true;//缓存字符
返回“”;//将其删除
});
}
log('access',/[access]/g=>',replace('access',/[access]/g));
log('cell phones',/[el]/g=>',replace('cell phones',/[el]/g))代码>单线版本的“记忆”逻辑
较短的版本:
"cell phones".replace(/[el]/g, (seen => m => m in seen ? m : seen[m] = ''))({}))
您可以缓存删除的字符并防止进一步删除,第二个要替换的参数将是一个函数!整个jQuery库是一个单行程序。。。如果你想写短代码,为什么不使用箭头函数的简洁体形式呢?在单个参数周围也不需要括号。所以a=>b
而不是(a)=>{return b;}
。
"cell phones".replace(/[el]/g, (seen => m => m in seen ? m : seen[m] = ''))({}))