2016-10-31 8 views
1

Ich habe eine Liste von Wörtern durch Komma getrennt. Wie entferne ich ein Wort (Variable) mit RegEx und ohne einen Raum hinter sich zu lassen?RegEx lässt unerwünschten Speicherplatz hinter

Ansicht Beispielcode:

var testClasses = document.getElementsByTagName("div")[0].className; 
 
var classToRemove = "test3"; 
 

 
document.getElementsByTagName('p')[0].innerHTML = "Removing class ." + classToRemove + " from: <strong>" + testClasses + "</strong>"; 
 

 
var re = new RegExp(classToRemove + "\s?", "g"); 
 
testClasses = testClasses.replace(re, ""); 
 

 
// I ran into the same problem trying to be more specific 
 
// var re = new RegExp("(\S+\s?)*(" + classToRemove + "\s?)(\S+\s?)*", "g"); 
 
// testClasses = testClasses.replace(re, "$1$3"); 
 

 

 
document.getElementsByTagName('p')[1].innerHTML = "becomes: <strong>" + testClasses + "</strong>" + " // which looks great on the DOM."; 
 
console.log(testClasses); 
 
console.log(testClasses.split(' '));
<div class="test1 test2 test3 test4 test5"></div> 
 
<p></p> 
 
<p></p> 
 
<p>However, if you check console, the space is there. <br><strong>How do I remove this extra space?</strong> Without having to run a second replace.</p>

Einschränkungen:

  • ich das erkennen konnte mit String oder Array-Manipulation erreicht werden. Ich versuche jedoch, RegEx zu verstehen.
  • Verwenden Sie nur eine RegEx. Zwei Ersetzungen erscheinen hässlich und unnötig.
  • Ich kann nicht davon ausgehen, dass vor/nach dem gegebenen Wort immer ein Leerzeichen stehen wird.
+1

Um Whitespace zu entsprechen, benötigen Sie das Literal '\ s' im Muster. Sie definieren einen optionalen Buchstaben 's' mit' \ s? 'In' new RegExp (classToRemove + "\ s?", "G"); '. Meintest du 'new RegExp (classToRemove +" \\ s? "," G ");'? Und die letzte Lösung, die Sie brauchen, ist 'var re = new RegExp (" \\ s * "+ classToRemove," g ");'. "" \\ s * "'. Beachten Sie, dass ('\ s *') null oder mehr Leerzeichen entspricht. –

+0

beliebig viele Leerzeichen -> '\ s *' – vlaz

+0

@ WiktorStribiżew was ist, wenn die Liste nur das Wort hat, das ich entfernen möchte? Es wird KEINE Leerzeichen enthalten, daher muss es optional sein. – warkentien2

Antwort

2

Darf ich Sie interessieren in Element.classList? Diese API ermöglicht die Mutation des Attributs class über geeignete Methoden wie .add(), .remove() und .toggle(). Dies ist viel besser als eine eigene RegExp-Lösung.


Wenn es nicht eine RegExp Lösung sein muss, könnte man Array.filter versuchen:

'alpha bravo charlie' 
    .split(' ') 
    .filter(function(token) { return token !== 'alpha' }) 
    .join(' '); 

Aber lassen Sie uns mit der Lösung Ihrer RegExp Rätsel auszukommen. In einer Zeichenfolge "alpha bravo charlie" möchten Sie in der Lage sein, alle drei Tokens zu entfernen, ohne unnötige Leerzeichen vor, nach oder zwischen den verbleibenden Token zu hinterlassen. Dies kann mit Hilfe eines negative look-ahead assertion (x(?!y)) erfolgen:

function removeToken(text, token) { 
    var pattern = new RegExp('(\\s+(?!\\S+\\s+))?' + token + '\\s*'); 
    return text.replace(pattern, ''); 
} 

Der negative Vorgriffs Behauptung (\s(?!\S+\s+))? enthalten nur den Raum vor dem Token, wenn kein Platz ist nach das Token. Auf diese Weise vermeiden Sie, beide Leerzeichen zu entfernen, wenn Sie ein Token in der Mitte entfernen.Der Ausdruck lautet "Erfassen eines oder mehrerer Leerzeichen, es sei denn, ihnen folgen ein oder mehrere Leerzeichen, auf die ein oder mehrere Leerzeichen folgen". Die "Nicht-Space-Charaktere" stimmen mit Ihrem Token überein, ohne dass Sie das Token ebenfalls dorthin injizieren müssen. Da diese führenden Leerzeichen nicht immer vorhanden sind, wird die Erfassungsgruppe optional durch eine nachgestellte ? Option ergänzt.

diesen Code testen, können wir alle vier Fälle laufen:

var text = 'alpha bravo charlie'; 
var tests = { 
    // <token to remove>: <resulting string> 
    'alpha': 'bravo charlie', 
    'bravo': 'alpha charlie', 
    'charlie': 'alpha bravo', 
    'delta': 'alpha bravo charlie', 
}; 

Object.keys(tests).forEach(function(token) { 
    var expected = tests[token]; 
    var result = removeToken(text, token); 
    console.log('removed "' + token + '" got "' + result + '" which is', expected === result ? 'correct' : 'WRONG'); 
}); 

und dass

removed "alpha" got "bravo charlie" which is correct 
removed "bravo" got "alpha charlie" which is correct 
removed "charlie" got "alpha bravo" which is correct 
removed "delta" got "alpha bravo charlie" which is correct 

gedruckt werden soll Wenn Sie Ihre Token erwarten Zeichen enthalten, die eine Bedeutung in RegExp haben, können Sie Ich möchte escape them.

+0

Ich stieß auf dieses Problem beim Versuch, eine .classList-Lösung für IE9 zu erhalten. Also habe ich versucht, stattdessen einen add/remove von .className zu erstellen. Der negative Look-ahead-Link ist eine Goldmine, danke! Ich kann jetzt auch '' (\\ s + (? = \\ S + $))? ' + token + '\ s *' 'positive Vorausschau. Danke für die sehr aufschlussreiche Antwort! Danke, dass du 'RegExp.escape' hervorgehoben hast – warkentien2

1

Leerzeichen Passend Sie \s im Muster wörtlichen müssen, bedeutet, dass ein Backslash und s. Sie haben einen optionalen Buchstaben s mit "\s?" in new RegExp(classToRemove + "\s?", "g") definiert, da in einem C-String-Literal zwei Backslashes erforderlich sind, um einen umgekehrten Schrägstrich zu definieren.

Verwenden

var re = new RegExp("\\s*" + classToRemove, "g"); 

Beachten Sie, dass "\\s*" (\s*) entspricht null oder mehr Leerzeichen. Da classToRemove keine Nicht-Wort-Zeichen enthalten kann, braucht es keine Regex-Entschlüsselung, daher füge ich diesen Code hier nicht hinzu.

Wenn es nur ein einziges Auftreten eines Klassennamens sein kann, entfernen Sie den "g" globalen Modifikator und nur var re = new RegExp("\\s*" + classToRemove) verwenden.

+0

Ich hatte keine Ahnung, dass es plötzlich eine C-Zeichenfolge wurde (meine erste Programmiersprache war C). Perfekte Erklärung! Vielen Dank! – warkentien2

+1

* C Zeichenfolgenliteral * ist eine Zeichenfolge, die Escape-Sequenzen wie '\ n' für einen Zeilenumbruch,' \ r' für Zeilenumbrüche usw. erlaubt. Wenn Sie '/ \ s /' verwenden, wird der umgekehrte Schrägstrich nicht als behandelt eine Escape-Sequenz, es ist ein wörtlicher Backslash + 's'. –

+0

Was ist, wenn ich das erste Element aus der Liste entfernen möchte? Dieses vorangehende '\ s *' hilft nicht. – warkentien2

Verwandte Themen