Kolikrát jste potřebovali spustit více operací nahrazení na stejném řetězci? Není to tak špatné, ale může to být trochu únavné, pokud takto často píšete kód.
str = str. replace( /&(?!#?\w+;)/g , '&' ). replace( /"([^"]*)"/g , '“$1”' ). replace( /</g , '<' ). replace( />/g , '>' ). replace( /…/g , '…' ). replace( /“/g , '“' ). replace( /”/g , '”' ). replace( /‘/g , '‘' ). replace( /’/g , '’' ). replace( /—/g , '—' ). replace( /–/g , '–' );
Běžným trikem, jak zkrátit takový kód, je vyhledat náhradní hodnoty pomocí objektu jako hashovací tabulky. Zde je jednoduchá implementace tohoto.
var hash = { '<' : '<' , '>' : '>' , '…' : '…', '“' : '“' , '”' : '”' , '‘' : '‘' , '’' : '’' , '—' : '—' , '–' : '–' }; str = str. replace( /&(?!#?\w+;)/g , '&' ). replace( /"([^"]*)"/g , '“$1”' ). replace( /[<>…“”‘’—–]/g , function ( $0 ) { return hash[ $0 ]; });
Tento přístup má však určitá omezení.
- Vzory vyhledávání se opakují v tabulce hash a ve třídě znaků regulárního výrazu.
- Vyhledávání i nahrazování jsou omezeny na prostý text. Proto musely první a druhé nahrazení zůstat ve výše uvedeném kódu oddělené. První nahrazení použilo vyhledávací vzor regulárního výrazu a druhé použilo zpětný odkaz v nahrazujícím textu.
- Náhrady neprobíhají kaskádovitě. I proto musela druhá operace výměny zůstat oddělená. Chci text jako
"this"
nejprve nahradit“this”
a nakonec skončí jako“this”
. - Nefunguje v Safari 2.xa dalších starých prohlížečích, které nepodporují použití funkcí pro generování náhradního textu.
S několika řádky String.prototype
cukr, se všemi těmito problémy se můžete vypořádat.
String.prototype.multiReplace = function ( hash ) { var str = this, key; for ( key in hash ) { str = str.replace( new RegExp( key, 'g' ), hash[ key ] ); } return str; };
Nyní můžete použít kód takto:
str = str.multiReplace({ '&(?!#?\\w+;)' : '&' , '"([^"]*)"' : '“$1”' , '<' : '<' , '>' : '>' , '…' : '…', '“' : '“' , '”' : '”' , '‘' : '‘' , '’' : '’' , '—' : '—' , '–' : '–' });
Pokud vám záleží na pořadí nahrazování, měli byste si být vědomi toho, že aktuální specifikace JavaScriptu nevyžaduje zvláštní pořadí výčtu při opakování vlastností objektu pomocí for..in
. Nejnovější verze velké čtyřky prohlížečů (IE, Firefox, Safari, Opera) však všechny používají pořadí vložení, což umožňuje, aby to fungovalo tak, jak je popsáno (shora dolů). Návrhy ECMAScript 4 naznačují, že konvence pořadí vložení bude v tomto standardu formálně kodifikována.
Pokud se potřebujete starat o nepoctivé vlastnosti, které se objeví, když si lidé zahrají s Object.prototype, můžete kód aktualizovat následovně:
String.prototype.multiReplace = function ( hash ) { var str = this, key; for ( key in hash ) { if ( Object.prototype.hasOwnProperty.call( hash, key ) ) { str = str.replace( new RegExp( key, 'g' ), hash[ key ] ); } } return str; };
Volání hasOwnProperty
metoda na Object.prototype
spíše než na hash
object přímo umožňuje, aby tato metoda fungovala, i když hledáte řetězec "hasOwnProperty".
Dejte mi vědět, jestli si myslíte, že je to užitečné.