2016-01-02 14 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

、正規表現はそれを行うことができますが、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

3

あなたがArray#indexOfArray#lastIndexOfにしてArray#filterを使用することができます要素が繰り返されているかどうかを確認してください。

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"/>

アイデアです:重複した文字を取得し、入力文字列から削除します。キャラクタが特殊正規表現のメタキャラクタ(つまり、 g1.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")が使用されている)である場合、エスケープが必要であることに注意してください。

もう一つのアイデアは、私はちょうど(文字クラスから重複したシンボルを削除し、特殊な正規表現文字をエスケープして)ここに私の独自の実装を追加し、his deleted answerWashington Guedesに属し:

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"/>

NOTE:改行記号もサポートしたい場合は、.[^]または[\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

関連する問題