Couper / couper / couper en JavaScript le dernier caractère de la chaîne


1975

J'ai une chaîne, 12345.00et j'aimerais qu'elle revienne 12345.0.

J'ai regardé trim, mais il semble que ce soit seulement un espace blanc et sliceque je ne vois pas comment cela fonctionnerait. Aucune suggestion?


36
Vous vous souciez de l'arrondi? 12345.46 = 12345.5 ou 12345.4?
RSolberg

9
Savez-vous quel est le suffixe ou voulez-vous diviser et supprimer le dernier mot en fonction de vos soulignements?
Cᴏʀʏ

65
Ho ho ho, @RSolberg: vous ne pouvez pas arrondir une chaîne!
Ziggy

50
@Ziggy dit quoi? Math.round('0.5') === 1;)
TWiStErRob

16
@TWiStErRob Oh JavaScript, que vais-je faire de toi? * secoue la tête *
Chuck Le Butt

Réponses:


3216

Vous pouvez utiliser la fonction de sous - chaîne :

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

C'est la réponse acceptée, mais selon les conversations ci-dessous, la syntaxe de tranche est beaucoup plus claire:

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


23
@Kheu - la notation de tranche est beaucoup plus nette pour moi. J'utilisais auparavant la version sous-chaîne. Merci!
Matt Ball

32
pardonnez-moi si je me trompe, mais n'avez-vous pas besoin d'attribuer à nouveau la valeur de str.substring à str? J'aimestr = str.substring(0, str.length -1);
Doug Molineux

10
Les méthodes slice& substringsont toutes les mêmes; sauf que le slice()accepte un index négatif, par rapport à la fin de la chaîne, mais pas le substring, il renvoie une out-of-bounderreur
Amol M Kulkarni

20
Au cas où quelqu'un se demanderait, substringest 11% plus rapide que slice. jsperf.com/js-slice-vs-substring-test
BenR

19
la sous-chaîne est une micro-optimisation insensée que je ne pense pas que vous devriez faire. Maximisez d'abord la lisibilité. Optimisez ensuite les fruits à faible pendaison si nécessaire.
Alfred

1307

Vous pouvez utiliser la tranche ! Vous devez juste vous assurer de savoir comment l'utiliser. Les # positifs sont relatifs au début, les nombres négatifs sont relatifs à la fin.

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

75
Comparé à la solution acceptée, c'est beaucoup plus élégant et peut être utilisé même avec des chaînes créées dynamiquement
Sameer Alibhai

1
J'aime cette façon, car elle fonctionne avec la pensée php pour la fonction substr, plus facile à mémoriser et à écrire à la volée.
Pathfinder

2
@SameerAlibhai Je suis d'accord avec vous, mais la substringméthode ne pourrait-elle pas être utilisée également sur les chaînes dynamiques? En utilisant la str.length pour obtenir dynamiquement la longueur?
Doug Molineux

Il faut ajouter que le premier index est inclusif et le second exclusif.
Miscreant

@KevinBeal, vous pouvez simplement utiliser F12 dans les navigateurs traditionnels et l'entrer dans la console, fonctionne sur n'importe quelle page et vous avez même du contexte et pouvez charger des bibliothèques.
TWiStErRob

263

Vous pouvez utiliser la méthode de sous- chaîne des objets chaîne JavaScript:

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

Il supprime inconditionnellement les quatre derniers caractères de la chaîne s.

Cependant, si vous souhaitez supprimer conditionnellement les quatre derniers caractères, uniquement s'ils sont exactement _bar :

var re = /_bar$/;
s.replace(re, "");

107
slicec'est mieux ici. s.slice(0, -4)
Tim Down du

12
Alternativement: à la tranche (0, - "_ bar" .length) (utile si l'on ne veut pas coder en dur le nombre de caractères)
Mahn

3
J'aime celui-ci car il donne également de l'aide pour remplacer une fin spécifiée.
Mike Graf

162

La méthode la plus simple consiste à utiliser la sliceméthode de la chaîne, qui autorise les positions négatives (correspondant aux décalages à la fin de la chaîne):

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

Si vous aviez besoin de quelque chose de plus général pour tout supprimer après (et y compris) le dernier trait de soulignement, vous pouvez faire ce qui suit (tant qu'il sest garanti de contenir au moins un trait de soulignement):

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


67

Pour un nombre comme votre exemple, je recommanderais de le faire sur substring:

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

Notez cependant que cela arrondira le nombre, ce que j'imagine souhaitable, mais peut-être pas:

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


11
+1 C'est ce dont OP a besoin, oubliez la fausse supposition qu'il y a des chaînes à couper.
naugtur

2
Ce n'est pas une fausse hypothèse, OP parle de chaînes. Votre hypothèse est fausse, car OP ne parle pas d'arrondir les nombres.
Fernando

30

Utilisation de la fonction de tranche de JavaScript:

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

Cela pourrait être utilisé pour supprimer «_bar» à la fin d'une chaîne, de n'importe quelle longueur.


19

Une expression régulière est ce que vous recherchez:

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


Votre solution fonctionne, mais la réponse d'Alex est plus complète. Je vais donc accepter le sien. Merci!
Albert

1
Cela résout un problème connexe de suppression conditionnelle plutôt que de troncature aveugle
Aaron


9

Que diriez-vous:

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


9

Utilisez l'expression régulière:

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


En plus de ne pas être compatible Unicode, cela ne correspond pas non plus aux sauts de ligne.
user4642212

7
  1. (. *), capture plusieurs fois n'importe quel caractère

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

  1. ., correspond au dernier caractère, dans ce cas

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

  1. $, correspond à la fin de la chaîne

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


9
J'aime ça parce que malgré .splice () vous avez trouvé un moyen d'utiliser une expression régulière.
QueueHammer

En plus de ne pas être compatible Unicode, cela ne correspond pas non plus aux sauts de ligne.
user4642212


5

Voici une alternative que je ne pense pas avoir vue dans les autres réponses, juste pour le plaisir.

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

Pas aussi lisible ou simple qu'une tranche ou une sous-chaîne, mais vous permet de jouer avec la chaîne en utilisant de belles méthodes de tableau, donc à savoir.


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

4

Le chemin le plus court:

str.slice(0, -1); 

3

Si vous souhaitez effectuer un arrondi générique des flottants, au lieu de simplement couper le dernier caractère:

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: Il semble qu'il existe une fonction intégrée pour cela, comme le souligne Paolo. Cette solution est évidemment beaucoup plus propre que la mienne. Utilisez parseFloat suivi de toFixed




1

Performance

Aujourd'hui 2020.05.13 j'effectue des tests des solutions choisies sur Chrome v81.0, Safari v13.1 et Firefox v76.0 sur MacOs High Sierra v10.13.6.

Conclusions

  • le slice(0,-1)(D) est la solution rapide ou la plus rapide pour les chaînes courtes et longues et il est recommandé comme solution de cross-browser rapide
  • les solutions basées sur substring(C) et substr(E) sont rapides
  • les solutions basées sur des expressions régulières (A, B) sont lentes / moyennes rapides
  • les solutions B, F et G sont lentes pour les longues cordes
  • la solution F est la plus lente pour les chaînes courtes, G est la plus lente pour les chaînes longues

entrez la description de l'image ici

Détails

J'effectue deux tests pour les solutions A , B , C , D , E ( ext ), F , G (my)

  • pour une chaîne courte de 8 caractères (à partir de la question OP) - vous pouvez l'exécuter ICI
  • pour une chaîne longue de 1M - vous pouvez l'exécuter ICI

Les solutions sont présentées dans l'extrait ci-dessous

Voici des exemples de résultats pour Chrome pour chaîne courte

entrez la description de l'image ici


1

Sachez que String.prototype.{ split, slice, substr, substring }fonctionner sur des chaînes encodées UTF-16

Aucune des réponses précédentes n'est compatible avec Unicode. Les chaînes sont encodées en UTF-16 dans la plupart des moteurs JavaScript modernes, mais les points de code Unicode plus élevés nécessitent des paires de substitution , donc les anciennes méthodes de chaîne préexistantes fonctionnent sur les unités de code UTF-16, pas sur les points de code Unicode.

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"

De plus, les réponses RegExp ne correspondent pas aux sauts de ligne à la fin dans leur forme actuelle:

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

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


Utilisez l'itérateur de chaîne pour itérer les caractères

Le code Unicode utilise l'itérateur de la chaîne; voir Array.fromet ...diffuser . string[Symbol.iterator]peut être utilisé (par exemple au lieu destring ).

Voir également Comment diviser une chaîne Unicode en caractères en JavaScript .

Exemples:

const string = "ẞ🦊";

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

Utilisez les drapeaux set usur unRegExp

Le drapeau dotAllous fait .correspondre les caractères de saut de ligne, le drapeau unicodeouu active certaines fonctionnalités liées à Unicode.

Exemples:

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


Notez que certains graphèmes sont constitués de plus d'un point de code, par exemple 🏳️‍🌈qui se compose de la séquence 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308). Ici, même Array.fromdivisera cela en quatre «personnages». Il est possible de les faire correspondre avec la proposition de propriétés de séquence d'échappement de la propriété Unicode .


-1

Dans les cas où vous souhaitez supprimer quelque chose qui est proche de la fin d'une chaîne (dans le cas de chaînes de taille variable), vous pouvez combiner slice () et substr ().

J'avais une chaîne avec du balisage, construite dynamiquement, avec une liste de balises d'ancrage séparées par des virgules. La chaîne était quelque chose comme:

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

Pour supprimer la dernière virgule, j'ai fait ce qui suit:

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

-3

Essaye ça:

<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>

Vous pouvez également essayer l'exemple de travail en direct sur http://jsfiddle.net/informativejavascript/F7WTn/87/ .


3
Merci kamal. Cependant, j'ai marqué la réponse ci-dessus comme acceptée pour mes besoins. Remarquez la coche verte ci-dessus. Cependant, j'ai vérifié votre code. :) Maintenant, dans ma situation, je ne connais que la séquence de caractères de fin commune. Il serait préférable de commencer à vérifier à partir de la fin de la chaîne. Votre suggestion échouerait si j'ai une chaîne qui ressemble à "foo_b_bar" et que je veux seulement retirer le dernier "_bar". Merci quand même! C'est une expérience assez intéressante de poser une question il y a plus de 2 ans, et de recevoir toujours des réponses pour elle aujourd'hui. :)
Albert

-4

@Jason S:

Vous pouvez utiliser la tranche! Vous devez juste vous assurer de savoir comment l'utiliser. Les # positifs sont relatifs au début, les nombres négatifs sont relatifs à la fin.

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

Désolé pour mon graphomany mais le post a été tagué 'jquery' plus tôt. Donc, vous ne pouvez pas utiliser slice () dans jQuery car slice () est une méthode jQuery pour les opérations avec des éléments DOM, pas des sous-chaînes ... En d'autres termes, répondez @Jon Erickson suggère une solution vraiment parfaite.

Cependant, votre méthode fonctionnera à partir de la fonction jQuery, à l'intérieur de Javascript simple. Besoin de dire en raison de la dernière discussion dans les commentaires, que jQuery est beaucoup plus souvent une extension renouvelable de JS que son propre parent ECMAScript le plus connu.

Ici aussi existent deux méthodes:

comme notre:

string.substring(from,to) comme plus si l'index 'to' nulled renvoie le reste de la chaîne. donc: string.substring(from) positif ou négatif ...

et certains autres - substr () - qui fournissent une plage de sous-chaînes et la «longueur» ne peuvent être positifs que: string.substr(start,length)

Certains responsables suggèrent également que la dernière méthode string.substr(start,length)ne fonctionne pas ou fonctionne avec une erreur pour MSIE.


3
Que voulez-vous dire? String.prototype.sliceest une méthode native
naugtur

c'est seulement ce que tu as dit. Méthode native Javascript, mais aussi slice()méthode jQuery pour la manipulation DOM: API jQuery: .slice () . ET SÛR, cela PEUT ÊTRE FIGURÉ comme un héritage polymorphe de JS Array.slice (), mais ce sont deux méthodes différentes, et je pense qu'il faut le distinguer. Ce n'est donc qu'une approximation de ces connaissances.
swift

12
Si vous appelez .sliceune variable qui est une chaîne, elle fera exactement ce que l'OP voulait. Peu importe que ce soit "à l'intérieur de jQuery" et il n'y a aucun moyen qu'il puisse "interférer" de quelque manière que ce soit à moins que vous n'écrasiez String.prototypeavec jQuery, ce qui, j'en suis sûr, empêchera TOUT code javascript de fonctionner. Votre réponse dit simplement que l'autre réponse n'est pas bonne et l'argument que vous fournissez est incorrect.
naugtur

1
Je peux être d'accord avec @naugtur cette réponse est fausse, la méthode de tranche de la chaîne n'est pas effectuée par jQuery.
reconbot

1
Je pense que le point que naugtur faisait valoir était juste que, en pratique, vous pourriez vous retrouver avec une chaîne enveloppée par un objet jQuery (par exemple, si vous faites quelques .datamanipulations fantaisistes et que vous vous retrouvez avec cette "chaîne"), qui si vous l'appeliez slice, ne ferait pas ce que vous voulez. Cela dit, ce n'est pas vraiment une réponse utile.
mAAdhaTTah

-8

Utilisez la sous-chaîne pour obtenir tout à gauche de _bar. Mais vous devez d'abord obtenir l'instr de _bar dans la chaîne:

str.substring(3, 7);

3 est ce début et 7 est la longueur.


1
cela ne fonctionne que sur "foo_bar" et non sur "foo_foo_bar", la question portait sur une chaîne de n'importe quelle longueur mais avec une fin connue.
Design par Adrian
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.