2016-01-02 5 views
5

Я ищу регулярное выражение, которое удалит все символы, которые были повторены в строке. Я уже решил это с помощью цикла. Просто интересно, есть ли регулярное выражение, которое может сделать то же самое.Regex для удаления всех повторяющихся символов

это то, что я до сих пор:

function onlyUnique(str) { 
    var re = /(.)(?=.*\1)/g 
    return str.replace(re, ''); 
} 

Эта строка:

"rc iauauc!gcusa_usdiscgaesracg" 

должен в конечном итоге, как это:

" !_de" 
+1

Я хочу удалить каждый символ, который находится в строке более одного раза. –

+0

Это не дубликат [Regex удаляет повторяющиеся символы из строки по javascript] (http://stackoverflow.com/q/19301806/1529630). Это позволяет удалить все вхождения вместо того, чтобы оставить только первое. – Oriol

+0

^^ и вопрос, OP хотят удалить только последовательные повторы. – Tushar

ответ

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.

+0

Вот как я это сделал. Мне просто интересно, существует ли одно регулярное выражение, которое может это сделать. –

1

ну, не знаю, если регулярное выражение не может сделать это, но вы могли бы работать его, используя цикл, как:

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 

Demo :: jsFiddle

3

Вы можете использовать Array#filter с Array#indexOf и Array#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

Если вы хотите сделать это с помощью регулярных выражений, вы можете использовать свои собственные регулярные выражения с помощью функции обратного вызова внутри заменить.

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, "\\$&")).

Другая идея принадлежит Washington Guedes в his deleted answer, я просто добавить свою собственную реализацию здесь (с удалением дубликатов символов из класса символов и экранирования специальных регулярных выражений символов):

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] внутри шаблона регулярного выражения.

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, ''); 
} 
+0

Пожалуйста, добавьте некоторое объяснение в свой ответ. Ответы только на код, как правило, считаются некачественными – Tristan