2017-08-04 4 views
0

私は負の正規表現を置き換える必要がある問題で取り組んでいます。javascriptの正規表現の置換機能

私は、文字列text、正規表現パターンreと私はすべてのを適用することによりtext文字列にreパターンでサブ文字列と一致しない置き換えるnegativeReplace機能を持つようにしたい機能f

を変換している場合関数fを変換し、残りの部分を残してください。ここで

# input 
var text = " aa (bb) cc "; 
var re = /[\(].*?[\)]/g; 
var f = function(s){ return s.toUpperCase() } 
# expected output 
negativeReplace(text, re, f) 
# -> " AA (bb) CC " 

は、それが働いていたこれまでの

function negativeReplace(text, re, f){ 
    var output = "" 
    var boundary = 0; 
    while((match = re.exec(text)) != null){ 
    output += f(text.slice(boundary, match.index)) + match[0]; 
    boundary = match.index + match[0].length; 
    } 
    output += f(text.slice(boundary, text.length)); 
    return output; 
} 

私の最高の試みです!

function negativeReplace(text, re, f){ 
 
    var output = "" 
 
    var boundary = 0; 
 
    while((match = re.exec(text)) != null){ 
 
    output += f(text.slice(boundary, match.index)) + match[0]; 
 
    boundary = match.index + match[0].length; 
 
    } 
 
    output += f(text.slice(boundary, text.length)); 
 
    return output; 
 
} 
 

 
var text1 = " aa (bb) cc "; 
 
var text2 = " aa { bb } cc { dd } ee "; 
 

 
var f1 = function(s){ return s.toUpperCase() } 
 
var f2 = function(s){ return "_" + s + "_" } 
 

 
re = /[\({].*?[\)}]/g 
 

 
console.log(negativeReplace(text1, re, f1)) // AA (bb) CC 
 
console.log(negativeReplace(text2, re, f1)) // AA { bb } CC { dd } EE 
 
console.log(negativeReplace(text1, re, f2)) // _ aa _(bb)_ cc _ 
 
console.log(negativeReplace(text2, re, f2)) // _ aa _{ bb }_ cc _{ dd }_ ee

しかし、私の実装は複雑すぎるようです。 javascriptはすでにの機能を持っていますので、と一致するパターンです。 のような簡単な場合は、のように、数字以外のすべての文字を以外の文字に置き換えると、this postに解決策があります。

この問題を解決するにはどうすればよいですか(replaceを使用してコードを改善するにはどうすればよいですか)。

ありがとうございました。

+0

リンクされたポストは実際には置換される個々の文字に確実に一致する正規表現を使用するという点で、 "否定的な"正規表現ではありません。あなたの要件は実際には同じカテゴリにはありません。 – nnnnnn

+0

*その特定の式*、または*の*式のためにこれを行う必要がありますか?そして、あなたは現在、式にマッチする文字列の一部を置き換えているので、実際にここで何をしようとしているのかははっきりしません。 –

+0

@ T.J.Crowder私の問題では、私は何度もこの関数を使わなければなりません。 *その特定の表現*は、私の問題を記述するための単なるテストケースです。 ** ** ** **表現にマッチしないすべての部分文字列を置き換えます。私のコードをもっと慎重に見てください。私が書いたように、この記事はいくつかのテストケースで動作しました。ありがとうございました –

答えて

1

私はちょうど.replace()でそれを行うための方法を考えることはできませんが、私は.split().map()、および.join()を使用して1つのステートメントでそれを行うための方法を考えることができます。

.split()で使用する正規表現にキャプチャカッコがある場合、一致するテキストが結果の配列に含まれるため、偶数インデックスの配列要素はすべて正規表現と一致しないビットになります。奇数のインデックスを持つ要素は、正規表現にマッチしたビットになります。だから、:

function negativeReplace(str, re, f) { 
 
    return str 
 
    .split(re) 
 
    .map(function(v, i) { return i % 2 === 0 && v ? f(v) : v }) 
 
    .join("") 
 
} 
 

 
var text1 = " aa (bb) cc "; 
 
var text2 = " aa { bb } cc { dd } ee "; 
 
var text3 = " aa { bb }{ dd } ee "; // example with no text between two matching substrings 
 

 
var f1 = function(s){ return s.toUpperCase() } 
 
var f2 = function(s){ return "_" + s + "_" } 
 

 
re = /([\({].*?[\)}])/  // <--- Note the added parens 
 

 
console.log(negativeReplace(text1, re, f1)) // AA (bb) CC 
 
console.log(negativeReplace(text2, re, f1)) // AA { bb } CC { dd } EE 
 
console.log(negativeReplace(text1, re, f2)) // _ aa _(bb)_ cc _ 
 
console.log(negativeReplace(text2, re, f2)) // _ aa _{ bb }_ cc _{ dd }_ ee _ 
 
console.log(negativeReplace(text3, re, f2)) // _ aa _{ bb }{ dd }_ ee _

EDIT:正規表現は、隣接する二つのサブストリングに一致した場合、その後.split()は、それらの2試合の間のテキストに空の文字列を返しますので、i % 2 === 0 && vテストは&& vが含まれていることに注意してください、と私は」これらの空の文字列で変換関数を呼びたくないと仮定していました。明らかにの場合は空の文字列を変換したいとします(たとえば、f2()関数はtext3"__"を挿入します)、&& v部分を削除するだけです。

+0

ありがとうございます。 'regex grouping'を使って' split 'について新しいことを学びます。 –

関連する問題