2017-03-13 7 views
2

正規表現の範囲を使用して配列やループを回避しようとしていますが、範囲内の各文字の最初のインスタンスを一度置き換えたいだけです。Regex - 一致範囲がユニーク文字ごとに1回のみ

私は注文を保証することができず、再注文できないため、範囲を使用しています。例えば

:正規表現の範囲内

"access".replace(/[access]/g, '') = "cs", instead of "". "cell phones".replace(/[el]/g) = "cl phones", instead of "c phons"

ダブルスはとにかく冗長であり、この場合、それはまた、第二の発生を交換させるべきではありません。

これが不可能な場合は、他に何かを考える必要があります。

+0

あなたが削除文字をキャッシュし、さらに削除を防ぐことができ、交換する第二parametterは、関数を代わりになります! –

答えて

2

これは、文字が以前に発生していたかどうかを確認するためのルック・バックを必要とするため、保持する必要があります。しかし、JSはそれをサポートしていません。いくつかのアイデアについては、 "JS look-behind regexp"を検索してください。

function replace(str, regex) { 
 
    var cache = {};   // the cache object 
 
    return str.replace(regex, function(m) { 
 
    if(cache[m]) return m; // if we already removed an instance of this matched character then don't remove any further instances 
 
    
 
    // otherwise ... 
 
    cache[m] = true;  // cache the character 
 
    return '';    // remove it 
 
    }); 
 
} 
 

 
console.log('"access", /[access]/g => ', replace("access", /[access]/g)); 
 
console.log('"cell phones", /[el]/g => ', replace("cell phones", /[el]/g));
:私は上記のコメントで言ったことの一例として

const rev = s => s.split('').reverse().join(''); 
 

 
const testData = [ 
 
    ["access", 'access'], 
 
    ["cell phones", 'el'] 
 
]; 
 

 
function match(s, chrs) { 
 
    const reg = new RegExp(`([${chrs}])(?!.*\\1)`, "g"); 
 
    return rev(rev(s).replace(reg, '')); 
 
} 
 
    
 
testData.forEach(([input, chrs]) => console.log("input", input, "gives", match(input, chrs)));

+0

うわー。私は箱入りのアプローチを考えるのが好きです。 –

0

:あなたはルック先読みを使用できるように古典的なアプローチは、文字列を逆にすることです

注:とすると、渡された正規表現はすべて文字セット(あなたが呼んだときの範囲)です。ちょうど/[...]/gが許されています。そうでないと動作は望み通りになりません。

0

"覚えている"ロジックのシングルライン版。

"cell phones".replace(/[el]/g, (() => { let seen = []; return m => seen.includes(m) ? m : (seen.push(m),''); })()) 

短いバージョン:

"cell phones".replace(/[el]/g, (seen => m => m in seen ? m : seen[m] = ''))({})) 
+0

jQueryライブラリ全体がonelinerです。むしろコードを読みやすくしてください –

+1

短いコードを書いてみたいのであれば、簡潔な本体の矢関数を使わないのはなぜですか?また、単一のパラメーターの周りにかっこは必要ありません。したがって、 '(a)=> {return b;}の代わりに' a => b'を使います。 } '。 –

+0

@ torazaburoありがとう、それを更新しました。 –

関連する問題