Trimmen Sie ein bestimmtes Zeichen aus einer Zeichenfolge


118

Was ist das JavaScript- Äquivalent zu dieser C#Methode:

var x = "|f|oo||"; 
var y = x.Trim('|'); //  "f|oo"

C # schneidet das ausgewählte Zeichen nur am Anfang und Ende der Zeichenfolge ab!

Antworten:


154

Eine Zeile reicht aus:

var x = '|f|oo||';
var y = x.replace(/^\|+|\|+$/g, '');
document.write(x + '<br />' + y);

^\|+   beginning of the string, pipe, one or more times
|      or
\|+$   pipe, one or more times, end of the string

Eine allgemeine Lösung:

function trim (s, c) {
  if (c === "]") c = "\\]";
  if (c === "\\") c = "\\\\";
  return s.replace(new RegExp(
    "^[" + c + "]+|[" + c + "]+$", "g"
  ), "");
}

chars = ".|]\\";
for (c of chars) {
  s = c + "foo" + c + c + "oo" + c + c + c;
  console.log(s, "->", trim(s, c));
}


35

Wenn ich es gut verstanden habe, möchten Sie ein bestimmtes Zeichen nur entfernen, wenn es am Anfang oder am Ende der Zeichenfolge steht (Beispiel: ||fo||oo||||sollte werden foo||oo). Sie können eine Ad-hoc-Funktion wie folgt erstellen:

function trimChar(string, charToRemove) {
    while(string.charAt(0)==charToRemove) {
        string = string.substring(1);
    }

    while(string.charAt(string.length-1)==charToRemove) {
        string = string.substring(0,string.length-1);
    }

    return string;
}

Ich habe diese Funktion mit dem folgenden Code getestet:

var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );

3
Dies wäre ein lustiger Test für den Garbage Collector, aber ich würde nicht empfehlen, Ihre Kunden diesem Test zu unterziehen.
Sorensen

17

Sie können einen regulären Ausdruck verwenden, z.

var x = "|f|oo||";
var y = x.replace(/^[\|]+|[\|]+$/g, "");
alert(y); // f|oo

AKTUALISIEREN:

Wenn Sie dies in eine Funktion verallgemeinern möchten, können Sie Folgendes tun:

var escapeRegExp = function(strToEscape) {
    // Escape special characters for use in a regular expression
    return strToEscape.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

var trimChar = function(origString, charToTrim) {
    charToTrim = escapeRegExp(charToTrim);
    var regEx = new RegExp("^[" + charToTrim + "]+|[" + charToTrim + "]+$", "g");
    return origString.replace(regEx, "");
};

var x = "|f|oo||";
var y = trimChar(x, "|");
alert(y); // f|oo

17

um diese Frage auf dem neuesten Stand zu halten:

Hier ist ein Ansatz, den ich mit dem ES6-Spread-Operator gegenüber der Regex-Funktion wählen würde.

function trimByChar(string, character) {
  const first = [...string].findIndex(char => char !== character);
  const last = [...string].reverse().findIndex(char => char !== character);
  return string.substring(first, string.length - last);
}

Verbesserte Version nach @fabians Kommentar (kann nur Zeichenfolgen verarbeiten, die dasselbe Zeichen enthalten)

function trimByChar(string, character) {
  const arr = Array.from(string);
  const first = arr.indexOf(character);
  const last = arr.reverse().indexOf(character);
  return string.substring(first + 1, string.length - last - 1);
}

2
Ich weiß, dass Regexes hier übertrieben sind, aber warum sollten Sie diese spezielle Implementierung wählen?
Nicholas Shanks

2
diese Implementierung, weil ich persönlich finde, dass sie gut lesbar ist. Kein Regex, nur weil der Entscheidungsbaum innerhalb der Regex-Engines viel größer ist. und insbesondere, weil die zum Trimmen verwendeten regulären Ausdrücke Abfragezeichen enthalten, die zu einem Backtracking innerhalb der regulären Ausdrücke führen. Solche Engines kompilieren das Muster häufig zu Bytecode, der Maschinenanweisungen ähnelt. Die Engine führt dann den Code aus und springt von Anweisung zu Anweisung. Wenn ein Befehl fehlschlägt, wird er zurückverfolgt, um einen anderen Weg zu finden, um mit der Eingabe übereinzustimmen. Ergo ist viel mehr los als nötig.
Robin F.

Vielen Dank für Ihre Antwort, obwohl ich wollte, dass Sie erklären, warum Sie dies anderen Methoden ohne Regex vorziehen - ich hoffte auf mehr als nur "Ich finde es lesbar", nehme ich an.
Nicholas Shanks

1
@RobinF. Sie denken, findIndex () und reverse () enthalten keine Schleifen? Denk nochmal.
Andrew

1
Zwei Anmerkungen: Eine Zeichenfolge, die nur das zu trimmende Zeichen enthält, wird überhaupt nicht gekürzt. Der andere Punkt ist: Das Explodieren des Strings in ein Array mit dem Spread-Operator verwirrt babel und transformiert es in [].concat(string)das, was nicht das gewünschte Ergebnis ist. Verwenden Array.from(string)wird funktionieren.
Fabian

14

Eine Version ohne Regex, die das Auge schont:

const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);

Für Anwendungsfälle, in denen wir sicher sind, dass sich die Zeichen an den Rändern nicht wiederholen.


ziemlich interessant ... also gibt split ein undefiniertes Element zurück, das jedem geteilten Trennzeichen entsprichtconst trim = (str, chars) => str.split(chars).filter(x => { Boolean(x); console.log(typeof(x), x, Boolean(x)); }).join(chars); const str = "#//#//abc#//test#//end#//"; console.log(trim(str, '#//'));
TamusJRoyce

10

Wenn Sie mit längeren Zeichenfolgen arbeiten, sollte dies meiner Meinung nach die meisten anderen Optionen übertreffen, indem Sie die Anzahl der zugewiesenen Zeichenfolgen auf null oder eins reduzieren:

function trim(str, ch) {
    var start = 0, 
        end = str.length;

    while(start < end && str[start] === ch)
        ++start;

    while(end > start && str[end - 1] === ch)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trim('|hello|world|', '|'); // => 'hello|world'

Oder wenn Sie aus mehreren Zeichen schneiden möchten:

function trimAny(str, chars) {
    var start = 0, 
        end = str.length;

    while(start < end && chars.indexOf(str[start]) >= 0)
        ++start;

    while(end > start && chars.indexOf(str[end - 1]) >= 0)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimAny('|hello|world   ', [ '|', ' ' ]); // => 'hello|world'
// because '.indexOf' is used, you could also pass a string for the 2nd parameter:
trimAny('|hello| world  ', '| '); // => 'hello|world'

BEARBEITEN: Zum Spaß schneiden Sie Wörter (anstatt einzelne Zeichen)

// Helper function to detect if a string contains another string
//     at a specific position. 
// Equivalent to using `str.indexOf(substr, pos) === pos` but *should* be more efficient on longer strings as it can exit early (needs benchmarks to back this up).
function hasSubstringAt(str, substr, pos) {
    var idx = 0, len = substr.length;

    for (var max = str.length; idx < len; ++idx) {
        if ((pos + idx) >= max || str[pos + idx] != substr[idx])
            break;
    }

    return idx === len;
}

function trimWord(str, word) {
    var start = 0,
        end = str.length,
        len = word.length;

    while (start < end && hasSubstringAt(str, word, start))
        start += word.length;

    while (end > start && hasSubstringAt(str, word, end - len))
        end -= word.length

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimWord('blahrealmessageblah', 'blah');

1
Ich bevorzuge diese Lösung, weil sie tatsächlich effizient ist und nicht nur kurz.
TekHedd

Ich bin damit einverstanden, dass es bevorzugt werden sollte. Ersetzt eine Antwort, die ich gegeben hatte.
TamusJRoyce

9

Dies kann mehrere Zeichen gleichzeitig kürzen:

String.prototype.trimChars = function (c) {
  var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
  return this.replace(re,"");
}

var x = "|f|oo||"; 
x =  x.trimChars('|'); // f|oo

var y = "..++|f|oo||++..";
y = y.trimChars('|.+'); // f|oo

var z = "\\f|oo\\"; // \f|oo\

// For backslash, remember to double-escape:
z = z.trimChars("\\\\"); // f|oo

@ Fubo: Nein, nicht wirklich. Es ist eine Demo. Wenn Sie sie in eine Konsole einfügen, wird nur das Ergebnis ausgedruckt. Aber ich verstehe, dass es verwirrend sein kann, deshalb habe ich es bearbeitet.
Marlar

2

Wenn Sie diese Funktionen in Ihrem Programm definieren, verfügen Ihre Zeichenfolgen über eine aktualisierte Version trim, mit der alle angegebenen Zeichen gekürzt werden können:

String.prototype.trimLeft = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("^[" + charlist + "]+"), "");
};

String.prototype.trim = function(charlist) {
	return this.trimLeft(charlist).trimRight(charlist);
};

String.prototype.trimRight = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("[" + charlist + "]+$"), "");
};

var withChars = "/-center-/"
var withoutChars = withChars.trim("/-")
document.write(withoutChars)

Quelle

https://www.sitepoint.com/trimming-strings-in-javascript/


1

Meines Wissens hat jQuery keine eingebaute Funktion, nach der Sie fragen. Mit Javascript können Sie jedoch einfach Ersetzen verwenden, um den Inhalt Ihrer Zeichenfolge zu ändern:

x.replace(/|/i, ""));

Dies ersetzt alle Vorkommen von | mit nichts.


Gibt es eine Möglichkeit, | zu entfernen? nur am Anfang / Ende?
Fubo

Ich denke tatsächlich, dass dieser Beitrag Sie auf dem neuesten Stand
Ole Haugset

@fubo Sicher ... Werfen Sie eine solche $für nur am Ende: "||spam|||".replace(/\|+$/g, "")oder eine solche ^für nur am Anfang:"||spam|||".replace(/^\|+/g, "")
Ruffin

1

Dieser schneidet alle führenden und nachfolgenden Begrenzer ab

const trim = (str, delimiter) => {
  const pattern = `[^\\${delimiter}]`;
  const start = str.search(pattern);
  const stop = str.length - str.split('').reverse().join('').search(pattern);
  return str.substring(start, stop);
}

const test = '||2|aaaa12bb3ccc|||||';
console.log(trim(test, '|')); // 2|aaaa12bb3ccc

1

Ich würde vorschlagen, sich lodash anzuschauen und wie sie das umgesetzt haben trim Funktion .

Die Dokumentation und die Quelle finden Sie unter Lodash Trim Trimmen, um den genauen Code für das Trimmen .

Ich weiß, dass dies keine genaue Antwort auf Ihre Frage liefert, aber ich denke, es ist gut, auf eine solche Frage einen Verweis auf eine Bibliothek zu setzen, da andere dies möglicherweise nützlich finden.


1
@ TamusJRoyce nicht das gleiche
gdbdable

@devi Ich kann nur zustimmen. danke für den Kommentar. Gute Antwort bei der Suche nach einem von der Community unterstützten Tool.
TamusJRoyce

1

Der beste Weg, um diese Aufgabe zu lösen, ist (ähnlich wie bei der PHP- trimFunktion):

function trim( str, charlist ) {
  if ( typeof charlist == 'undefined' ) {
    charlist = '\\s';
  }
  
  var pattern = '^[' + charlist + ']*(.*?)[' + charlist + ']*$';
  
  return str.replace( new RegExp( pattern ) , '$1' )
}

document.getElementById( 'run' ).onclick = function() {
  document.getElementById( 'result' ).value = 
  trim( document.getElementById( 'input' ).value,
  document.getElementById( 'charlist' ).value);
}
<div>
  <label for="input">Text to trim:</label><br>
  <input id="input" type="text" placeholder="Text to trim" value="dfstextfsd"><br>
  <label for="charlist">Charlist:</label><br>
  <input id="charlist" type="text" placeholder="Charlist" value="dfs"><br>
  <label for="result">Result:</label><br>
  <input id="result" type="text" placeholder="Result" disabled><br>
  <button type="button" id="run">Trim it!</button>
</div>

PS: Warum habe ich meine Antwort gepostet, als die meisten Leute es schon einmal gemacht haben? Da ich in allen Antworten "den besten" Fehler gefunden habe: Alle haben das '+' - Meta anstelle von '*' verwendet. Die Ursache trimmuss Zeichen entfernen, WENN SIE STARTEN UND / ODER ENDEN. In anderen Fällen wird jedoch die ursprüngliche Zeichenfolge zurückgegeben .


0

Hier ist eine Antwort, die mehrere Zeichen annehmen kann:

var trim = function (s, t) {
  var tr, sr
  tr = t.split('').map(e => `\\\\${e}`).join('')
  sr = s.replace(new RegExp(`^[${tr}]+|[${tr}]+$`, 'g'), '')
  return sr
}

0

Ich mag die Lösung von @ Pho3niX83 ...

Erweitern wir es mit "Wort" anstelle von "Zeichen" ...

function trimWord(_string, _word) {

    var splitted = _string.split(_word);

    while (splitted.length && splitted[0] === "") {
        splitted.shift();
    }
    while (splitted.length && splitted[splitted.length - 1] === "") {
        splitted.pop();
    }
    return splitted.join(_word);
};

0
function trim(text, val) {
    return text.replace(new RegExp('^'+val+'+|'+val+'+$','g'), '');
}

0
"|Howdy".replace(new RegExp("^\\|"),"");

(Beachten Sie das doppelte Escapezeichen , das \\erforderlich ist, um einen tatsächlich einfachen Schrägstrich in der Zeichenfolge zu haben , der dann zum Escapezeichen| im regExp führt. )

Nur wenige Zeichen benötigen regExp-Escaping. unter ihnen der Rohrbetreiber.



-1
String.prototype.TrimStart = function (n) {
    if (this.charAt(0) == n)
        return this.substr(1);
};

String.prototype.TrimEnd = function (n) {
    if (this.slice(-1) == n)
        return this.slice(0, -1);
};

Es entfernt nur ein Vorkommen, schneidet aber nicht, bis der Charakter vollständig getrimmt ist
KoalaBear

1
Überschreiben Sie nicht den Standard-String-Prototyp, da Sie später nach Problemen fragen. Erstellen Sie Ihre eigenen separaten Funktionen an anderer Stelle.
Rooby

-2

Versuchen Sie diese Methode:

var a = "anan güzel mi?";
if (a.endsWith("?"))   a = a.slice(0, -1);  
document.body.innerHTML = a;


1
Warum? Was macht das? Wie funktioniert es? Nur-Code-Antworten gelten in SO als minderwertig. Erläutern Sie Ihre Antwort, damit OP und zukünftige Besucher daraus lernen können.
Keine Panik
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.