JavaScript нарезать / вырезать / обрезать последний символ в строке


1976

У меня есть строка, 12345.00и я хотел бы ее вернуть 12345.0.

Я посмотрел trim, но похоже, что это только обрезка пробелов, и sliceя не вижу, как это будет работать. Какие-либо предложения?


36
Вы заботитесь о округлении? 12345,46 = 12345,5 или 12345,4?
RSolberg

9
Знаете ли вы, что такое суффикс, или вы хотите разделить и удалить последнее слово на основе подчеркивания?
Cᴏʀʏ

65
Хо-хо-хо, @RSolberg: ты не можешь закруглить строку!
Зигги

50
@ Зигги говорит что? Math.round('0.5') === 1;)
TWiStErRob

16
@TWiStErRob Ой JavaScript, что я собираюсь делать с тобой? * качает головой *
Чак Ле Батт

Ответы:


3217

Вы можете использовать функцию подстроки :

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

Это принятый ответ, но в соответствии с приведенными ниже разговорами синтаксис среза намного понятнее:

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


23
@Kheu - обозначение среза намного чище для меня. Ранее я использовал версию подстроки. Спасибо!
Мэтт Болл

32
простите, если я ошибаюсь, но вам не нужно снова присваивать значение str.substring для str? Нравитсяstr = str.substring(0, str.length -1);
Дуг Молинью

10
Эти sliceи substringметоды все самое то же самое; кроме того, что slice()принимает отрицательный индекс относительно конца строки, но не тот substring, что выдает out-of-boundошибку
Amol M Kulkarni

20
Если кому-то интересно, substringэто на 11% быстрее, чем slice. jsperf.com/js-slice-vs-substring-test
BenR

19
подстрока - это безумная микрооптимизация, которую я не думаю, что вам следует это делать. Максимизируйте для удобочитаемости сначала. Затем оптимизируйте низко висящие фрукты, если это необходимо.
Альфред

1307

Вы можете использовать ломтик ! Вы просто должны убедиться, что знаете, как им пользоваться. Положительные числа относятся к началу, отрицательные числа - к концу.

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

75
По сравнению с принятым решением это более элегантно и может использоваться даже с динамически создаваемыми строками
Sameer Alibhai,

1
Мне нравится этот способ, потому что он работает с php-мышлением для функции substr, его легче запомнить и писать на лету.
следопыт

2
@SameerAlibhai Я согласен с вами, но нельзя ли использовать этот substringметод и для динамических строк? Используя str.length для динамического получения длины?
Даг Молинью

Следует добавить, что первый индекс является включающим, а второй - эксклюзивным.
Miscreant

@KevinBeal вы можете просто использовать F12 в основных браузерах и вводить его в консоли, работать на любой странице, у вас даже есть контекст и вы можете загружать библиотеки.
TWiStErRob

263

Вы можете использовать метод substring строковых объектов JavaScript:

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

Безоговорочно удаляет последние четыре символа из строки s.

Однако, если вы хотите условно удалить последние четыре символа, только если они точно _bar :

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

107
sliceздесь лучше s.slice(0, -4)
Тим Даун

12
В качестве альтернативы: s.slice (0, - "_ bar" .length) (полезно, если не требуется жестко задавать количество символов)
Mahn

3
Мне нравится этот, потому что он также помогает заменить указанное окончание.
Майк Граф

162

Самый простой способ - использовать sliceметод строки, который допускает отрицательные позиции (соответствующие смещению от конца строки):

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

Если вам нужно что-то более общее, чтобы удалить все после (и в том числе) последнего подчеркивания, вы можете сделать следующее (при условии, что sоно обязательно содержит хотя бы одно подчеркивание):

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


67

Для числа, подобного вашему примеру, я бы рекомендовал сделать это снова substring:

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

Обратите внимание, что на самом деле это будет округлять число, что, я думаю, желательно, но, возможно, нет:

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


11
+1 Это то, что нужно ОП, забудьте про ложное предположение, что есть строки, которые нужно обрезать.
naugtur

2
Это не ложное предположение, OP говорит о строках. Ваше ложное предположение, потому что OP не говорит о округлении чисел.
Фернандо

30

Используя функцию слайса JavaScript:

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

Это может быть использовано для удаления '_bar' в конце строки любой длины.


19

Регулярное выражение - это то, что вы ищете:

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


Ваше решение работает, но ответ Алекса является более полным. Поэтому я приму его. Спасибо!
Альберт

1
Это решает связанную проблему условного удаления, а не слепого усечения
Аарон



9

Используйте регулярное выражение:

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


Помимо отсутствия поддержки Unicode, это также не соответствует разрывам строк.
user4642212

7
  1. (. *), захватывает любой символ несколько раз

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

  1. ., соответствует последнему символу, в этом случае

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

  1. $, соответствует концу строки

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


9
Мне это нравится, потому что, несмотря на .splice (), вы нашли способ использовать регулярные выражения.
QueueHammer

Помимо отсутствия поддержки Unicode, это также не соответствует разрывам строк.
user4642212


5

Вот альтернатива, которую я не думаю, что видел в других ответах, просто для удовольствия.

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

Не такой разборчивый или простой, как слайс или подстрока, но он позволяет вам играть со строкой, используя несколько хороших методов массива, так что стоит знать.


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


3

Если вы хотите сделать общее округление чисел, а не просто обрезать последний символ:

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

РЕДАКТИРОВАТЬ: Кажется, что существует встроенная функция для этого, как указывает Паоло. Это решение, очевидно, намного чище, чем мое. Используйте parseFloat с последующим toFixed




1

Представление

Сегодня 2020.05.13 я выполняю тесты выбранных решений на Chrome v81.0, Safari v13.1 и Firefox v76.0 на MacOs High Sierra v10.13.6.

Выводы

  • slice(0,-1)(D) является быстрым или самым быстрым решением для коротких и длинных строк , и рекомендуются в качестве быстрого решения кроссбраузерного
  • решения, основанные на substring(C) и substr(E), являются быстрыми
  • решения на основе регулярных выражений (A, B) медленные / средние быстрые
  • решения B, F и G являются медленными для длинных струн
  • решение F является самым медленным для коротких строк, G является самым медленным для длинных строк

введите описание изображения здесь

подробности

Я выполняю два теста для решений A , B , C , D , E ( ext ), F , G (мой)

  • для 8-символьной короткой строки (из вопроса ОП) - вы можете запустить ее ЗДЕСЬ
  • для 1М длинной строки - вы можете запустить ее ЗДЕСЬ

Решения представлены в следующем фрагменте

Вот пример результатов для Chrome для короткой строки

введите описание изображения здесь


1

Имейте в виду, что String.prototype.{ split, slice, substr, substring }работают с кодированными строками UTF-16

Ни один из предыдущих ответов не поддерживает Unicode. Строки кодируются как UTF-16 в большинстве современных механизмов JavaScript, но для более высоких кодовых точек Unicode требуются суррогатные пары , поэтому более старые, уже существующие строковые методы работают с кодовыми единицами UTF-16, а не с кодовыми точками 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"

Кроме того, ответы RegExp не соответствуют разрывам строк в конце в их текущей форме:

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

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


Используйте итератор строк для итерации символов

Юникод-ориентированный код использует итератор строки; увидеть Array.fromи ...распространить . string[Symbol.iterator]можно использовать (например, вместо string).

Также смотрите Как разделить строку Unicode на символы в JavaScript .

Примеры:

const string = "ẞ🦊";

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

Используйте sи uфлаги наRegExp

В dotAllили sфлаг марки .соответствуют символы разрыва строки, то unicodeили uфлаг позволяет определенные Unicode-функции , связанные.

Примеры:

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


Обратите внимание, что некоторые графемы состоят из более чем одной кодовой точки, например, 🏳️‍🌈которая состоит из последовательности 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308). Здесь даже Array.fromразделим это на четыре «персонажа». Сопоставление с ними возможно с помощью свойства свойства Unicode, которое экранируется от последовательности .


-1

В случаях, когда вы хотите удалить что-то, что находится ближе к концу строки (в случае строк переменного размера), вы можете объединить slice () и substr ().

У меня была строка с разметкой, динамически построенная, со списком тегов привязки, разделенных запятой. Строка была что-то вроде:

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

Чтобы удалить последнюю запятую, я сделал следующее:

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

-3

Попробуй это:

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

Вы также можете попробовать живой пример работы на http://jsfiddle.net/inforrativejavascript/F7WTn/87/ .


3
Спасибо, Камаль. Тем не менее, я отметил ответ выше, как принятый для моих нужд. Обратите внимание на зеленую галочку выше. Хотя я проверил твой код. :) Теперь, в моей ситуации, я знаю только общую последовательность конечных символов. Было бы лучше просто начать проверку с конца строки. Ваше предложение потерпит неудачу, если у меня будет строка, похожая на «foo_b_bar», и я хочу только удалить последний «_bar». Спасибо хоть! Довольно интересный опыт задать вопрос более 2 лет назад, и до сих пор получать ответы на него сегодня. :)
Альберт

-4

@ Джейсон С:

Вы можете использовать ломтик! Вы просто должны убедиться, что знаете, как им пользоваться. Положительные числа относятся к началу, отрицательные числа - к концу.

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

Извините за мою графоманию, но пост был помечен как 'jquery' ранее. Таким образом, вы не можете использовать slice () внутри jQuery, потому что slice () - это метод jQuery для операций с элементами DOM, а не с подстроками ... Другими словами, ответ @Jon Erickson предлагает действительно идеальное решение.

Однако ваш метод будет работать из функции jQuery внутри простого Javascript. В связи с последним обсуждением в комментариях нужно сказать, что jQuery является гораздо более часто обновляемым расширением JS, чем его собственный родительский наиболее известный ECMAScript.

Здесь также существуют два метода:

как наш:

string.substring(from,to) как плюс, если 'to' index nulled возвращает остаток строки. итак: string.substring(from) положительный или отрицательный ...

и некоторые другие - substr () - которые предоставляют диапазон подстроки и «length» могут быть только положительными: string.substr(start,length)

Также некоторые сопровождающие полагают, что последний метод string.substr(start,length)не работает или работает с ошибкой для MSIE.


3
Что вы имеете в виду? String.prototype.sliceэто нативный метод
naugtur

это только то, что ты сказал. Собственный метод Javascript, но также и slice()метод jQuery для манипулирования DOM: API jQuery: .slice () . И конечно, это можно изобразить как полиморфное наследование JS Array.slice (), но это два разных метода, и я думаю, что это нужно различать. Так что это всего лишь приближение к этим знаниям.
быстрое

12
Если вы вызываете .sliceпеременную, которая является строкой, она будет делать именно то, что хотел OP. Не имеет значения, находится ли он «внутри jQuery», и нет никакого способа, которым он мог бы «вмешиваться» каким-либо образом, если только вы не перезапишите String.prototypejQuery, что, я уверен, предотвратит работу ЛЮБОГО кода javascript. Ваш ответ просто говорит, что другой ответ не является хорошим, и аргумент, который вы предоставляете, неверен
naugtur

1
Я могу согласиться с @naugtur, что этот ответ неправильный, jQuery не использует метод среза строки.
перепроверять

1
Я думаю, что идея naugtur заключалась в том, что, возможно, вы могли бы получить строку, обернутую объектом jQuery (например, если вы сделали какую-то необычную .dataманипуляцию и в итоге получили эту «строку»), которая, если вы вызываете sliceее, не будет делать то, что вы хотите. Тем не менее, это не очень полезный ответ.
mAAdhaTTah

-8

Используйте подстроку, чтобы получить все слева от _bar. Но сначала вы должны получить значение _bar в строке:

str.substring(3, 7);

3 - это начало, а 7 - длина.


1
это работает только для "foo_bar", а не для "foo_foo_bar", вопрос был о строке любой длины, но с известным концом.
Дизайн Адриана
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.