如何使用Javascript删除字符串中的最后一个字符?可以使用chop/slice/trim方法吗?

2523

我有一个字符串12345.00,我想将它转换成12345.0

我已经查看了trim,但它似乎只能修剪空格,还有slice,但我不知道它怎么用。 有什么建议吗?


42
你在意四舍五入吗?12345.46应该取12345.5还是12345.4? - RSolberg
10
你知道后缀是什么吗?或者你想根据下划线分割并移除最后一个单词吗? - Cᴏʀʏ
25个回答

3923
你可以使用 substring 函数:

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

这是被接受的答案,但根据下面的交流,slice 语法更加清晰明了。

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


36
@Kheu - 切片表示法对我来说更加简洁。之前我一直在使用子字符串版本。谢谢! - Matt Ball
39
如果我说错了,请原谅,但您需要将str.substring的值分配给str吗?像这样:str = str.substring(0, str.length -1); - Doug Molineux
15
slice()substring()方法几乎相同,唯一的区别是slice()方法接受相对于字符串末尾的负索引,而substring()方法不接受,它会抛出“越界”错误。 - Amol M Kulkarni
31
如果有人想知道,substringslice 快11%。http://jsperf.com/js-slice-vs-substring-test - BenR
33
子字符串是一种疯狂的微观优化,我认为您不应该这样做。首先要最大程度地提高可读性。如果需要,可以优化低效部分。 - Alfred
显示剩余6条评论

1522

你可以使用slice!只需要确保你知道如何使用它。正数相对于开头,负数相对于结尾。

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

84
与已接受的解决方案相比,这种方式更加优雅,甚至可以用于动态创建的字符串。 - Sameer Alibhai
1
我喜欢这种方式,因为它符合php对于substr函数的思考方式,更容易记忆和即时编写。 - pathfinder
2
@SameerAlibhai 我同意你的观点,但是 substring 方法也可以用于动态字符串,通过使用 str.length 来动态获取长度。 - Doug Molineux
应该补充说明第一个索引是包含的,而第二个索引是不包含的。 - Miscreant
2
这个方法可以用来删除最后一个字符,但是如果你想删除变量数量的字符时要小心;.slice(0, -0)会返回一个空字符串! - Nigel Nelson
显示剩余3条评论

278
你可以使用 JavaScript 字符串对象的 substring 方法:

substring

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

它无条件地从字符串s中删除最后四个字符。

但是,如果你想要有条件地删除最后四个字符,仅当它们恰好为_bar时:

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

108
这里最好使用“slice”。s.slice(0, -4) - Tim Down
15
另一种方法是:s.slice(0, -"_bar".length)(如果不想硬编码字符数的话,这种方法很有用)。 - Mahn
4
我喜欢这个,因为它也提供了替换指定结尾的帮助。 - Mike Graf
1
第二个示例仅会在字符串中存在多个“_bar”实例时删除第一个实例。 - O Genthe

180

最简单的方法是使用字符串的slice方法,该方法允许使用负数位置(相对于字符串末尾的偏移量):

const s = "your string";
const withoutLastFourChars = s.slice(0, -4);
如果你需要更通用的方法来删除最后一个下划线及其后面的所有内容,只要确保变量s中至少包含一个下划线,就可以采用以下方法(使用JavaScript语言): ```js s.substring(0, s.lastIndexOf("_")) ```

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


72

对于像您的示例这样的数字,我建议优先使用此方法而非substring

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

请注意,这将实际舍入数字,虽然我想这是需要的,但不一定:

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


12
这就是OP所需要的,不要错误地假设有需要修剪的字符串。 - naugtur
6
这不是一个错误的假设,OP谈论的是字符串。你的假设是错误的,因为OP没有谈论四舍五入数字。 - Fernando

42

请注意String.prototype.{split,slice,substr,substring}的操作是基于UTF-16编码的字符串

先前的回答都没有考虑Unicode。 在大多数现代JavaScript引擎中,字符串被编码为UTF-16,但较高的Unicode代码点需要代理对,因此旧的、预先存在的字符串方法是基于UTF-16代码单元而不是Unicode代码点进行操作的。 参见:不要使用.split('')

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"

此外,正则表达式方法(如早期答案中所建议的)不匹配末尾的换行符:

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

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


使用字符串迭代器迭代字符

支持Unicode的代码应使用字符串的迭代器;请参见Array.from... spread。 也可以使用string[Symbol.iterator](例如,而不是string)。

另请参阅如何在JavaScript中将Unicode字符串拆分为字符

示例:

const string = "ẞ";

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

RegExp上使用su标志

dotAlls标志使.匹配换行符,unicodeu标志启用某些与Unicode相关的功能。 请注意,当使用u标志时,您可以消除不必要的转义字符,因为这些在u正则表达式中是无效的,例如\[是可以的,因为它会在没有反斜杠的情况下开始一个字符类,但\:不是,因为它是一个带有或不带有反斜杠的:,所以您需要删除反斜杠。

示例:

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也会将其拆分为四个“字符”。使用RegExp set notation and properties of strings proposal可以更轻松地匹配它们。

1
感谢您的解释。确实开阔了视野。 - alex

33

使用JavaScript的slice函数:

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

这可以用来移除任意长度的字符串末尾的“_bar”。


26
一个正则表达式是你需要寻找的东西:
let str = "foo_bar";
console.log(str.replace(/_bar$/, ""));


1
这解决了一个相关的问题,即有条件地删除而不是盲目地截断。 - Aaron

15
试试这个:

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


14

性能

今天2020年5月13日,我在MacOS High Sierra v10.13.6上对Chrome v81.0、Safari v13.1和Firefox v76.0进行了选定解决方案的测试。

结论

  • slice(0,-1)(D)是针对短字符串和长字符串快速或最快的解决方案,建议作为快速跨浏览器的解决方案
  • 基于substring (C) 和 substr(E) 的解决方案很快
  • 基于正则表达式的解决方案(A, B)的速度较慢/中等快
  • B、F和G的解决方案对于长字符串来说速度较慢
  • F的解决方案对于短字符串是最慢的,G的解决方案对于长字符串是最慢的

enter image description here

详情

我对解决方案ABCD、E(链接)、F和G进行了两次测试

  • 对于8个字符的短字符串(来自OP问题)- 您可以在这里运行它
  • 对于100万个字符的长字符串 - 您可以在这里运行它

以下是解决方案的代码:

function A(str) {
  return str.replace(/.$/, '');
}

function B(str) {
  return str.match(/(.*).$/)[1];
}

function C(str) {
  return str.substring(0, str.length - 1);
}

function D(str) {
  return str.slice(0, -1); 
}

function E(str) {
  return str.substr(0, str.length - 1);
}

function F(str) {
  let s= str.split("");
  s.pop();
  return s.join("");
}

function G(str) {
  let s='';
  for(let i=0; i<str.length-1; i++) s+=str[i];
  return s;
 }



// ---------
// TEST
// ---------

let log = (f)=>console.log(`${f.name}: ${f("12345.00")}`);

[A,B,C,D,E,F,G].map(f=>log(f));
This snippet only presents soutions

以下是Chrome处理短字符串的示例结果:

在此输入图片描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接