JavaScript hackt / schneidet / schneidet das letzte Zeichen in der Zeichenfolge ab

1973

Ich habe eine Zeichenfolge 12345.00und möchte, dass sie zurückkehrt 12345.0.

Ich habe es angeschaut trim, aber es sieht so aus, als würde es nur Leerzeichen abschneiden und sliceich sehe nicht, wie das funktionieren würde. Irgendwelche Vorschläge?

Phill Pafford
quelle
36
Interessieren Sie sich für Rundungen? 12345.46 = 12345.5 oder 12345.4?
RSolberg
9
Wissen Sie, was das Suffix ist, oder möchten Sie das letzte Wort basierend auf Ihren Unterstrichen teilen und entfernen?
30.
65
Ho ho ho, @RSolberg: Sie können keine Schnur runden !
Ziggy
50
@ Ziggy sagt was? Math.round('0.5') === 1;)
TWiStErRob
16
@TWiStErRob Oh JavaScript, was mache ich mit dir? * schüttelt den Kopf *
Chuck Le Butt

Antworten:

3214

Sie können die Teilzeichenfolgenfunktion verwenden:

let str = "12345.00";
str = str.substring(0, str.length - 1);
console.log(str);

Dies ist die akzeptierte Antwort, aber gemäß den folgenden Gesprächen ist die Slice- Syntax viel klarer:

let str = "12345.00";
str = str.slice(0, -1); 
console.log(str);

Jon Erickson
quelle
23
@ Kheu - die Slice-Notation ist für mich viel sauberer. Ich habe zuvor die Teilstring-Version verwendet. Vielen Dank!
Matt Ball
32
Verzeihen Sie mir, wenn ich falsch liege, aber müssen Sie str nicht erneut den Wert von str.substring zuweisen? Wiestr = str.substring(0, str.length -1);
Doug Molineux
10
Die slice& substringMethoden sind alle gleich; mit der Ausnahme, dass der slice()einen negativen Index relativ zum Ende des Strings akzeptiert, aber nicht den substring, wirft er einen out-of-boundFehler
Amol M Kulkarni
20
Falls sich jemand wundert, substringist 11% schneller als slice. jsperf.com/js-slice-vs-substring-test
BenR
19
Teilzeichenfolge ist eine verrückte Mikrooptimierung, die Sie meiner Meinung nach nicht tun sollten. Maximieren Sie zuerst die Lesbarkeit. Optimieren Sie dann bei Bedarf niedrig hängende Früchte.
Alfred
1306

Sie können Slice verwenden ! Sie müssen nur sicherstellen, dass Sie wissen, wie man es benutzt. Positive #s sind relativ zum Anfang, negative Zahlen sind relativ zum Ende.

js>"12345.00".slice(0,-1)
12345.0
Jason S.
quelle
75
Im Vergleich zur akzeptierten Lösung ist dies viel eleganter und kann auch mit dynamisch erstellten Zeichenfolgen verwendet werden
Sameer Alibhai
1
Ich mag diesen Weg, weil er mit PHP-Gedanken für die Substr-Funktion lebt, leichter zu merken und spontan zu schreiben ist.
Pathfinder
2
@SameerAlibhai Ich stimme Ihnen zu, aber konnte die substringMethode nicht auch für dynamische Zeichenfolgen verwendet werden? Indem Sie die Länge verwenden, um die Länge dynamisch zu ermitteln?
Doug Molineux
Es sollte hinzugefügt werden, dass der erste Index inklusive und der zweite exklusiv ist.
Miscreant
@ KevinBeal Sie können F12 einfach in Mainstream-Browsern verwenden und in die Konsole eingeben, funktioniert auf jeder Seite und Sie haben sogar Kontext und können Bibliotheken laden.
TWiStErRob
263

Sie können die Teilzeichenfolgenmethode von JavaScript-Zeichenfolgenobjekten verwenden:

s = s.substring(0, s.length - 4)

Es entfernt bedingungslos die letzten vier Zeichen aus der Zeichenfolge s .

Wenn Sie jedoch die letzten vier Zeichen bedingt entfernen möchten , nur wenn sie genau sind _bar :

var re = /_bar$/;
s.replace(re, "");
Alex Martelli
quelle
107
sliceist hier besser. s.slice(0, -4)
Tim Down
12
Alternativ: s.slice (0, - "_ bar" .length) (nützlich, wenn man die Anzahl der Zeichen nicht fest codieren möchte)
Mahn
3
Ich mag dieses, weil er auch Hilfe beim Ersetzen eines bestimmten Endes gibt.
Mike Graf
162

Die einfachste Methode ist die Verwendung der sliceMethode der Zeichenfolge, die negative Positionen zulässt (entsprechend Offsets vom Ende der Zeichenfolge):

const s = "your string";
const withoutLastFourChars = s.slice(0, -4);

Wenn Sie etwas Allgemeineres benötigen, um alles nach dem letzten Unterstrich zu entfernen (und einzuschließen), können Sie Folgendes tun (sofern sgarantiert mindestens ein Unterstrich enthalten ist):

const s = "your_string";
const withoutLastChunk = s.slice(0, s.lastIndexOf("_"));
console.log(withoutLastChunk);

Tim Down
quelle
67

Für eine Zahl wie Ihr Beispiel würde ich empfehlen, dies noch einmal zu tun substring:

console.log(parseFloat('12345.00').toFixed(1));

Beachten Sie jedoch, dass dies tatsächlich die Zahl rundet, was meiner Meinung nach erwünscht ist, aber vielleicht nicht:

console.log(parseFloat('12345.46').toFixed(1));

Paolo Bergantino
quelle
11
+1 Dies ist, was OP benötigt. Vergessen Sie die falsche Annahme, dass Zeichenfolgen gekürzt werden müssen.
Naugtur
2
Es ist keine falsche Annahme, OP spricht von Strings. Ihre Annahme ist falsch, da OP nicht über das Runden von Zahlen spricht.
Fernando
30

Verwenden der Slice-Funktion von JavaScript:

let string = 'foo_bar';
string = string.slice(0, -4); // Slice off last four characters here
console.log(string);

Dies kann verwendet werden, um '_bar' am Ende einer Zeichenfolge beliebiger Länge zu entfernen.

Akshay Joshi
quelle
19

Ein regulärer Ausdruck ist das, wonach Sie suchen:

let str = "foo_bar";
console.log(str.replace(/_bar$/, ""));

w35l3y
quelle
Ihre Lösung funktioniert, aber Alex 'Antwort ist umfassender. Also werde ich seine akzeptieren. Vielen Dank!
Albert
1
Dies löst ein damit verbundenes Problem des bedingten Entfernens und nicht des blinden Abschneidens
Aaron
10

Versuche dies:

const myString = "Hello World!";
console.log(myString.slice(0, -1));

Somwang Souksavatd
quelle
9

Wie wäre es mit:

let myString = "12345.00";
console.log(myString.substring(0, myString.length - 1));

Dariom
quelle
9

Verwenden Sie Regex:

let aStr = "12345.00";
aStr = aStr.replace(/.$/, '');
console.log(aStr);

Marc477
quelle
Abgesehen davon, dass es nicht Unicode-fähig ist, stimmt dies auch nicht mit Zeilenumbrüchen überein.
user4642212
7
  1. (. *) erfasst jedes Zeichen mehrmals

console.log("a string".match(/(.*).$/)[1]);

  1. ., stimmt in diesem Fall mit dem letzten Zeichen überein

console.log("a string".match(/(.*).$/));

  1. $, entspricht dem Ende der Zeichenfolge

console.log("a string".match(/(.*).{2}$/)[1]);

Websites
quelle
9
Ich mag das, weil Sie trotz .splice () einen Weg gefunden haben, einen regulären Ausdruck zu verwenden.
QueueHammer
Abgesehen davon, dass es nicht Unicode-fähig ist, stimmt dies auch nicht mit Zeilenumbrüchen überein.
user4642212
6

const str = "test!";
console.log(str.slice(0, -1));

dota2pro
quelle
3
Was fügt dies im Vergleich zu allen anderen Antworten hinzu?
Dan Dascalescu
5

Hier ist eine Alternative, die ich nicht in den anderen Antworten gesehen habe, nur zum Spaß.

var strArr = "hello i'm a string".split("");
strArr.pop();
document.write(strArr.join(""));

Nicht so lesbar oder einfach wie Slice oder Teilstring, aber Sie können mit der Saite mit einigen netten Array-Methoden spielen, die es wert sind, kennengelernt zu werden.

Mark Walters
quelle
4
debris = string.split("_") //explode string into array of strings indexed by "_"

debris.pop(); //pop last element off the array (which you didn't want)

result = debris.join("_"); //fuse the remainng items together like the sun
uofc
quelle
4

Der kürzeste Weg:

str.slice(0, -1); 
Idan
quelle
3

Wenn Sie generische Floats runden möchten, anstatt nur das letzte Zeichen zu kürzen:

var float1 = 12345.00,
    float2 = 12345.4567,
    float3 = 12345.982;

var MoreMath = {
    /**
     * Rounds a value to the specified number of decimals
     * @param float value The value to be rounded
     * @param int nrDecimals The number of decimals to round value to
     * @return float value rounded to nrDecimals decimals
     */
    round: function (value, nrDecimals) {
        var x = nrDecimals > 0 ? 10 * parseInt(nrDecimals, 10) : 1;
        return Math.round(value * x) / x;
    }
}

MoreMath.round(float1, 1) => 12345.0
MoreMath.round(float2, 1) => 12345.5
MoreMath.round(float3, 1) => 12346.0

EDIT: Es scheint, dass es dafür eine eingebaute Funktion gibt, wie Paolo betont. Diese Lösung ist offensichtlich viel sauberer als meine. Verwenden Sie parseFloat gefolgt von toFixed

PatrikAkerstrand
quelle
1
if(str.substring(str.length - 4) == "_bar")
{
    str = str.substring(0, str.length - 4);
}
Matthew Flaschen
quelle
1

Performance

Heute 2020.05.13 teste ich ausgewählte Lösungen unter Chrome v81.0, Safari v13.1 und Firefox v76.0 unter MacOs High Sierra v10.13.6.

Schlussfolgerungen

  • die slice(0,-1)(D) sind schnell oder schnellste Lösung für kurze und lange Ketten , und es wird so schnell Cross-Browser - Lösung empfohlen
  • Lösungen basierend auf substring(C) und substr(E) sind schnell
  • Lösungen, die auf regulären Ausdrücken (A, B) basieren, sind langsam / mittelschnell
  • Die Lösungen B, F und G sind für lange Saiten langsam
  • Lösung F ist für kurze Saiten am langsamsten, G für lange Saiten am langsamsten

Geben Sie hier die Bildbeschreibung ein

Einzelheiten

Ich führe zwei Tests für die Lösungen A , B , C , D , E ( ext ), F , G (my) durch.

  • für 8-stellige kurze Zeichenfolge (aus der OP-Frage) - Sie können sie HIER ausführen
  • für 1M lange Zeichenfolge - Sie können es HIER ausführen

Die Lösungen sind im folgenden Ausschnitt dargestellt

Hier sind Beispielergebnisse für Chrome für kurze Zeichenfolgen

Geben Sie hier die Bildbeschreibung ein

Kamil Kiełczewski
quelle
1

Beachten Sie, dass String.prototype.{ split, slice, substr, substring }UTF-16-codierte Zeichenfolgen verwendet werden

Keine der vorherigen Antworten ist Unicode-fähig. Zeichenfolgen werden in den meisten modernen JavaScript-Engines als UTF-16 codiert, höhere Unicode-Codepunkte erfordern jedoch Ersatzpaare. Daher arbeiten ältere, bereits vorhandene Zeichenfolgenmethoden mit UTF-16-Codeeinheiten und nicht mit Unicode-Codepunkten.

const string = "ẞ🦊";

console.log(string.slice(0, -1)); // "ẞ\ud83e"
console.log(string.substr(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.substring(0, string.length - 1)); // "ẞ\ud83e"
console.log(string.replace(/.$/, "")); // "ẞ\ud83e"
console.log(string.match(/(.*).$/)[1]); // "ẞ\ud83e"

const utf16Chars = string.split("");

utf16Chars.pop();
console.log(utf16Chars.join("")); // "ẞ\ud83e"

Außerdem stimmen die RegExp-Antworten nicht mit den Zeilenumbrüchen am Ende in ihrer aktuellen Form überein:

const string = "Hello, world!\n";

console.log(string.replace(/.$/, "").endsWith("\n")); // true
console.log(string.match(/(.*).$/) === null); // true


Verwenden Sie den String-Iterator, um Zeichen zu iterieren

Unicode-fähiger Code verwendet den Iterator der Zeichenfolge. sehen Array.fromund ...verbreiten . string[Symbol.iterator]kann verwendet werden (zB anstelle vonstring ).

Siehe auch So teilen Sie Unicode-Zeichenfolgen in Zeichen in JavaScript .

Beispiele:

const string = "ẞ🦊";

console.log(Array.from(string).slice(0, -1).join("")); // "ẞ"
console.log([
  ...string
].slice(0, -1).join("")); // "ẞ"

Verwenden Sie die sund u-Flaggen auf aRegExp

Das Flag dotAlloders macht .Zeichen für Zeilenumbrüche, das Flag unicodeoderu aktiviert bestimmte Unicode-bezogene Funktionen.

Beispiele:

const unicodeString = "ẞ🦊",
  lineBreakString = "Hello, world!\n";

console.log(lineBreakString.replace(/.$/s, "").endsWith("\n")); // false
console.log(lineBreakString.match(/(.*).$/s) === null); // false
console.log(unicodeString.replace(/.$/su, "")); // ẞ
console.log(unicodeString.match(/(.*).$/su)[1]); // ẞ

// Now `split` can be made Unicode-aware:

const unicodeCharacterArray = unicodeString.split(/(?:)/su),
  lineBreakCharacterArray = lineBreakString.split(/(?:)/su);

unicodeCharacterArray.pop();
lineBreakCharacterArray.pop();
console.log(unicodeCharacterArray.join("")); // "ẞ"
console.log(lineBreakCharacterArray.join("").endsWith("\n")); // false


Es ist zu beachten, dass einige Grapheme aus mehr als einem Codepunkt bestehen, z. B. 🏳️‍🌈der aus der Sequenz 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308) besteht. Hier Array.fromwird dies sogar in vier "Zeichen" aufgeteilt. Das Abgleichen dieser ist mit der Unicode-Eigenschaft möglich, die dem Vorschlag für Sequenzeigenschaften entgeht .

user4642212
quelle
-1

In Fällen, in denen Sie etwas entfernen möchten, das sich nahe am Ende einer Zeichenfolge befindet (bei Zeichenfolgen mit variabler Größe), können Sie Slice () und Substr () kombinieren.

Ich hatte eine Zeichenfolge mit dynamisch erstelltem Markup mit einer durch Komma getrennten Liste von Ankertags. Die Saite war so etwas wie:

var str = "<a>text 1,</a><a>text 2,</a><a>text 2.3,</a><a>text abc,</a>";

Um das letzte Komma zu entfernen, habe ich Folgendes getan:

str = str.slice(0, -5) + str.substr(-4);
bestafubana
quelle
-3

Versuche dies:

<script>
    var x="foo_foo_foo_bar";
    for (var i=0; i<=x.length; i++) {
        if (x[i]=="_" && x[i+1]=="b") {
            break;
        }
        else {
            document.write(x[i]);
        }
    }
</script>

Sie können das Live-Arbeitsbeispiel auch unter http://jsfiddle.net/informativejavascript/F7WTn/87/ ausprobieren .

Kamal
quelle
3
Danke Kamal. Ich habe die obige Antwort jedoch als für meine Bedürfnisse akzeptiert markiert. Beachten Sie das grüne Häkchen oben. Allerdings habe ich Ihren Code überprüft. :) Jetzt kenne ich in meiner Situation nur die gemeinsame Endzeichenfolge. Es ist besser, erst am Ende der Zeichenfolge mit der Überprüfung zu beginnen. Ihr Vorschlag würde fehlschlagen, wenn ich eine Zeichenfolge habe, die wie "foo_b_bar" aussieht, und ich möchte nur die letzte "_bar" entfernen. Trotzdem danke! Es ist eine interessante Erfahrung, vor über 2 Jahren eine Frage zu stellen und auch heute noch Antworten darauf zu erhalten. :)
Albert
-4

@ Jason S:

Sie können Slice verwenden! Sie müssen nur sicherstellen, dass Sie wissen, wie man es benutzt. Positive #s sind relativ zum Anfang, negative Zahlen sind relativ zum Ende.

js> 12345.00 .slice (0, -1) 12345.0

Entschuldigung für meine Graphomany, aber der Beitrag wurde früher mit 'jquery' markiert. So können Sie nicht verwenden slice () innerhalb jQuery weil slice () jQuery - Methode für den Betrieb mit DOM - Elemente, nicht Substrings ... Mit anderen Worten beantworten @ Jon Erickson vorschlagen wirklich perfekte Lösung.

Ihre Methode funktioniert jedoch mit der jQuery-Funktion in einfachem Javascript. Aufgrund der letzten Diskussion in den Kommentaren muss gesagt werden, dass jQuery sehr viel häufiger eine erneuerbare Erweiterung von JS ist als das bekannteste ECMAScript seines eigenen Elternteils.

Hier existieren auch zwei Methoden:

als unsere:

string.substring(from,to) as plus if 'to' index nulled gibt den Rest der Zeichenfolge zurück. also: string.substring(from) positiv oder negativ ...

und einige andere - substr () -, die einen Bereich von Teilzeichenfolgen und 'Länge' bereitstellen, können nur positiv sein: string.substr(start,length)

Einige Betreuer schlagen außerdem vor, dass die letzte Methode string.substr(start,length)für MSIE nicht funktioniert oder mit Fehlern funktioniert.

schnell
quelle
3
Was meinst du? String.prototype.sliceist eine native Methode
naugtur
es ist nur das, was du gesagt hast. Native Javascript-Methode, aber auch jQuery- slice()Methode für die DOM-Manipulation: jQuery-API: .slice () . Und sicher, das kann wie eine polymorphe Vererbung von JS Array.slice () dargestellt werden, aber es sind zwei verschiedene Methoden, und ich denke, es muss unterschieden werden. Es ist also nur eine Annäherung an dieses Wissen.
Schneller
12
Wenn Sie .sliceeine Variable aufrufen , die eine Zeichenfolge ist, wird sie genau das tun, was das OP wollte. Es spielt keine Rolle, ob es sich um "inside jQuery" handelt, und es kann auf keinen Fall "stören", es sei denn, Sie überschreiben String.prototypejQuery, was sicher verhindert, dass Javascript-Code funktioniert. Ihre Antwort besagt nur, dass die andere Antwort nicht gut ist und das von Ihnen angegebene Argument falsch ist.
Naugtur
1
Ich kann @naugtur zustimmen, dass diese Antwort falsch ist. Die Slice-Methode des Strings wird von jQuery nicht beeinflusst.
Reconbot
1
Ich denke, der Punkt, den Naugtur machte, war nur, dass Sie möglicherweise mit einer Zeichenfolge enden könnten, die von einem jQuery-Objekt umschlossen wird (z. B. wenn Sie eine ausgefallene .dataManipulation durchführen und mit dieser "Zeichenfolge" enden), die, wenn Sie slicesie aufrufen , würde nicht tun was du willst. Dies ist jedoch keine wirklich hilfreiche Antwort.
mAAdhaTTah
-8

Verwenden Sie Teilzeichenfolgen, um alles links von _bar anzuzeigen. Aber zuerst müssen Sie die Instrumente von _bar in der Zeichenfolge erhalten:

str.substring(3, 7);

3 ist der Start und 7 ist die Länge.

Griegs
quelle
1
Dies funktioniert nur bei "foo_bar", nicht bei "foo_foo_bar". Die Frage betraf einen String mit einer beliebigen Länge, aber einem bekannten Ende.
Entwurf durch Adrian