正则表达式:去除所有重复字符

5
我希望您能提供一个正则表达式,以删除字符串中重复的所有字符。我已经使用循环解决了这个问题。只是想知道是否有一个可以完成相同任务的正则表达式。
以下是我目前的代码:
function onlyUnique(str) {
  var re = /(.)(?=.*\1)/g
  return str.replace(re, '');
}

这个字符串:

"rc iauauc!gcusa_usdiscgaesracg"

应该最终呈现为这样:

" !_de"

1
我想删除字符串中出现超过一次的每个字符。 - user5738757
这不是Regex remove repeated characters from a string by javascript的重复。这个想要删除所有出现的字符而不是只留下第一个。 - Oriol
^^ 和问题是,OP 只想删除连续重复的部分。 - Tushar
一个简单的搜索和替换循环会更容易理解且性能更好。那么这有什么意义呢? - vitaly-t
5个回答

4
您可以使用 Array#filterArray#indexOfArray#lastIndexOf 来检查元素是否重复。

var str = "rc iauauc!gcusa_usdiscgaesracg";

// Split to get array
var arr = str.split('');

// Filter splitted array
str = arr.filter(function (e) {
    // If index and lastIndex are equal, the element is not repeated
    return arr.indexOf(e) === arr.lastIndexOf(e);
}).join(''); // Join to get string from array

console.log(str);
document.write(str);


1

如果你想用正则表达式来实现,你可以在replace中使用自己的正则表达式和回调函数。

var re = /(.)(?=.*\1)/g; 
var str = 'rc iauauc!gcusa_usdiscgaesracg';
var result = str;
str.replace(re, function(m, g1) {
    result = result.replace(RegExp(g1.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), '');
});
document.getElementById("r").innerHTML = "'" + result + "'";
<div id="r"/>

这个想法是:获取重复的字符,并从输入字符串中删除它。请注意,如果字符可能是特殊的regex元字符,则需要转义(因此使用g1.replace(/ [.*+?^ $ {}()| [\] \\] / g,“\\ $&amp;”))。
另一个想法来自Washington Guedes他已删除的答案中,我在此添加了自己的实现(从字符类中删除重复符号并转义特殊的regex字符)。

var s = "rc iauauc!gcusa_u]sdiscgaesracg]";
var delimiters= '[' + s.match(/(.)(?=.*\1)/g).filter(function(value, index, self) { // find all repeating chars
    return self.indexOf(value) === index;  // get unique values only
}).join('').replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ']'; // escape special chars
var regex = new RegExp(delimiters, 'g'); // build the global regex from the delimiters
var result = s.replace(regex, '');  // obtain the result
document.getElementById("r2").innerHTML = "'" + result + "'";
<div id="r2"/>

注意: 如果您想支持换行符,可以将正则表达式模式中的.替换为[^][\s\S]


1
你的正则表达式搜索重复字符对并仅删除第一个。因此,最新的重复字符不会被删除。
为解决这个问题,你应该同时删除所有重复项,但我不认为你可以用单个replace完成。
相反,我会建立一个映射,计算每个字符的出现次数,然后再次迭代字符串,将只出现一次的字符推入新字符串:
function onlyUnique(str) {
  var map = Object.create(null);
  for(var i=0; i<str.length; ++i)
    map[str[i]] = (map[str[i]] || 0) + 1;
  var chars = [];
  for(var i=0; i<str.length; ++i)
    if(map[str[i]] === 1)
      chars.push(str[i]);
  return chars.join('');
}

indexOf不同,哈希映射中的搜索平均是常数时间。因此,调用一个包含n个字符的字符串的成本将为n


这就是我做的。我只是在想是否有一个正则表达式可以完成这个任务。 - user5738757

1

好的,不清楚正则表达式是否能做到这一点,但是您可以使用for循环来解决,例如:

function unikChars(str) {
    store = [];
    for (var a = 0, len = str.length; a < len; a++) {
        var ch = str.charAt(a);
        if (str.indexOf(ch) == a && str.indexOf(ch, a + 1) == -1) {
            store.push(ch);
        }
    }
    return store.join("");
}

var str = 'rc iauauc!gcusa_usdiscgaesracg';
console.log(unikChars(str)); //gives  !_de

演示:jsFiddle


0
function onlyUnique(str) {
  // match the characters you want to remove
  var match = str.match(/(.)(?=.*\1)/g);
  if (match) {
    // build your regex pattern
    match = '[' + match.join('') + ']';
  }
  // if string is already unique return the string
  else {
    return str
  }
  // create a regex with the characters you want to remove      
  var re = new RegExp(match, 'g');
  return str.replace(re, '');
}

请在您的答案中添加一些解释。仅有代码的答案通常被认为是低质量的。 - Tristan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接