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!

Fubo
quelle

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));
}

Blatt
quelle
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, "|") + "'" );
Pho3niX83
quelle
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
neelsg
quelle
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);
}
Robin F.
quelle
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.

mbaer3000
quelle
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');
Jason Larke
quelle
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
Marlar
quelle
@ 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/

Chris Redford
quelle
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.

Ole Haugset
quelle
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
Dmitriy Botov
quelle
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.

zog7721
quelle
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 .

StoneCountry
quelle
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
}
AmitK
quelle
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);
};
Foxontherock
quelle
0
function trim(text, val) {
    return text.replace(new RegExp('^'+val+'+|'+val+'+$','g'), '');
}
Alexander Ladonin
quelle
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.

Frank Nocke
quelle
-1

Versuchen:

console.log(x.replace(/\|/g,''));
Mann Programmierer
quelle
-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);
};
Tobo
quelle
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;

Ali CAKIL
quelle
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