Edited at

JavaScriptで文字列から重複した値のみを抜き出す方法

More than 1 year has passed since last update.


はじめに

初投稿です。自分のメモ用ですが、もしお役に立てればコメントもらえれば嬉しいです。

分かりにくい箇所や間違い等ありましたらご指摘ください。


サンプルコード


regexp.js

//テスト用文字列

text = "ab*_\naB*_\nb";

// 重複文字が隣接するように並び替え
sorted_text = text.toLowerCase().split("").sort().join("");
console.log(sorted_text); //**__aabb

// [^]:全ての文字が対象
sample1 = sorted_text.match(/([^])\1+/g);
console.log(sample1); //[ '\n\n', '**', '__', 'aa', 'bb' ]

// .:全ての文字が対象だが改行文字は含まない
sample2 = sorted_text.match(/(.)\1+/g);
console.log(sample2); //[ '**', '__', 'aa', 'bb' ]

// \w:[A-Za-z0-9_]と同義
sample3 = sorted_text.match(/(\w)\1+/g);
console.log(sample3); //[ '__', 'aa', 'bb' ]



解説

最初に重複文字が隣接するようにソートします。

大文字・小文字を区別しないならソート前にtoLowerCase()で揃えます。

正規表現を用いて重複文字を抜き出すためmatch()を使います。

抜き出す文字がない場合はnullが返されるのでご注意ください。

/(.)\1+/gを例に取ります。

( )と\1の記述で\1が( )内の評価された値で置き換わります。

具体的には、([0-2])\1と書いた場合、00,11,22といった具合にパターンを見てくれます。

今回は改行以外の全ての文字が対象となる(.)を対象としているため、aa,**などがマッチします。

応用として([0-2])([a-c])/1/2 のように、2つ目以降の( )に対しても/2/3..../nで指定できます。

+は前の値が1回以上出現する場合にマッチします。

今回の例だと\1,すなわち(.)で評価された値が1回以上出現する場合にマッチします。

gは探している文字列が見つかった場合、次の文字列を引き続き探してくれます。

なければ最初の見つけた文字列のみ返されるためご注意ください。