如何使用 Javascript 砍掉/切片/修剪字符串中的最后一个字符?

How do I chop/slice/trim off last character in string using Javascript?

提问人:Phill Pafford 提问时间:6/5/2009 最后编辑:LiamPhill Pafford 更新时间:1/30/2022 访问量:2395454

问:

我有一个字符串,我希望它返回。12345.0012345.0

我看过,但看起来它只是在修剪空格,我不明白这是如何工作的。有什么建议吗?trimslice

JavaScript 切片 修剪

评论

42赞 RSolberg 6/5/2009
你关心四舍五入吗?12345.46 = 12345.5 还是 12345.4?
10赞 Cᴏʀʏ 8/30/2010
您知道后缀是什么,还是想根据下划线拆分和删除最后一个单词?

答:

3921赞 Jon Erickson 6/5/2009 #1

您可以使用子字符串函数:

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

评论

36赞 Matt Ball 4/13/2010
@Kheu - 切片符号对我来说更干净。我以前使用的是子字符串版本。谢谢!
39赞 Doug Molineux 7/16/2011
如果我错了,请原谅我,但你不需要再次将 str.substring 的值分配给 str 吗?喜欢str = str.substring(0, str.length -1);
15赞 Amol M Kulkarni 4/9/2013
& 方法都大同小异;除了 接受相对于字符串末尾的负索引,但不接受 ,它会抛出错误slicesubstringslice()substringout-of-bound
31赞 BenR 4/16/2014
如果有人想知道,比 .jsperf.com/js-slice-vs-substring-testsubstringslice
33赞 Alfred 7/9/2014
子字符串是疯狂的微优化,我认为你不应该这样做。首先最大限度地提高可读性。然后根据需要优化唾手可得的果实。
10赞 dariom 6/5/2009 #2

怎么样:

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

72赞 Paolo Bergantino 6/5/2009 #3

对于像您的示例这样的数字,我建议您这样做:substring

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

请注意,这实际上会使数字四舍五入,不过,我认为这是需要的,但可能不是:

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

评论

11赞 naugtur 12/6/2012
+1 这就是 OP 需要的,忘记有字符串需要修剪的错误假设。
6赞 Fernando 6/2/2015
这不是一个错误的假设,OP 谈论的是字符串。你的假设是错误的,因为 OP 不谈论四舍五入的数字。
5赞 PatrikAkerstrand 6/5/2009 #4

如果要对浮点数进行通用舍入,而不仅仅是修剪最后一个字符:

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

编辑:正如 Paolo 指出的那样,似乎存在一个内置功能。这个解决方案显然比我的要干净得多。使用 parseFloat,后跟 toFixed

1521赞 Jason S 6/5/2009 #5

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

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

评论

84赞 Sameer Alibhai 7/4/2012
与公认的解决方案相比,这更加优雅,甚至可以与动态创建的字符串一起使用
1赞 pathfinder 3/15/2013
我喜欢这种方式,因为它与 php 的 substr 功能思维相结合,更容易记住和即时编写。
2赞 Doug Molineux 9/3/2014
@SameerAlibhai 我同意你的看法,但该方法不能也用于动态字符串吗?通过使用 str.length 动态获取长度?substring
0赞 Miscreant 7/8/2015
应该补充的是,第一个索引是包容性的,第二个索引是排他性的。
2赞 Nigel Nelson 4/23/2019
这适用于删除最后一个字符,但如果要删除可变数量的字符,请小心; 将返回一个空字符串!.slice(0, -0)
-4赞 swift 8/4/2010 #6

@Jason S:

你可以用切片!你只需要 确保您知道如何使用它。 正 #s 是相对于 开头,负数是 相对于末尾。

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

对不起,我的 graphomany,但帖子早些时候被标记为“jquery”。因此,您不能在 jQuery 中使用 slice(),因为 slice( 是用于使用 DOM 元素而不是子字符串进行操作的 jQuery 方法...... 换句话说,埃里克森@Jon回答了真正完美的解决方案。

但是,您的方法将在简单的 Javascript 中从 jQuery 函数中工作。 需要说的是,由于上次在评论中的讨论,jQuery比他自己的父公司最知名的ECMAScript更经常是JS的可再生扩展。

这里还存在两种方法:

作为我们的:

string.substring(from,to) 如果 'to' 索引 nulled 返回字符串的其余部分。 所以:正面或负面......string.substring(from)

和其他一些 - substr() - 提供子字符串范围和 'length' 只能是正数: string.substr(start,length)

此外,一些维护者建议最后一种方法对 MSIE 不起作用或有错误。string.substr(start,length)

评论

3赞 naugtur 12/5/2012
你是什么意思? 是本机方法String.prototype.slice
0赞 swift 12/5/2012
只有你说的。Javascript 原生方法,还有用于 DOM 操作的 jQuery 方法:jQuery API:.slice()。当然,这可以看作是 JS Array.slice() 的多态继承,但它是两种不同的方法,我认为需要区分它。所以这只是对这种知识的近似。slice()
12赞 naugtur 12/6/2012
如果你调用一个字符串变量,它将执行 OP 想要的操作。它是否“在 jQuery 内部”并不重要,除非您用 jQuery 覆盖,否则它不可能以任何方式“干扰”,我相信这将阻止任何 javascript 代码工作。你的答案只是说其他答案不好,你提供的论点不正确。.sliceString.prototype
1赞 reconbot 6/11/2013
我可以同意这个答案是错误的@naugtur字符串的切片方法不受 jQuery 的影响。
1赞 mAAdhaTTah 4/26/2016
我认为 naugtur 的观点是,你最终可能会得到一个由 jQuery 对象包装的字符串(例如,如果你做一些花哨的操作并最终得到这个“字符串”),如果你调用它,它不会做你想要的。也就是说,这并不是一个有用的答案。.dataslice
-8赞 griegs 8/30/2010 #7

使用子字符串将所有内容放在_bar的左侧。但首先你必须在字符串中获取 _bar 的 instr:

str.substring(3, 7);

3 是开始,7 是长度。

评论

1赞 Design by Adrian 9/21/2012
这仅适用于“foo_bar”,不适用于“foo_foo_bar”,问题是关于任何长度但已知结尾的字符串。
278赞 Alex Martelli 8/30/2010 #8

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

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

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

但是,如果要有条件地删除最后四个字符,则仅当它们完全是:_bar

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

评论

108赞 Tim Down 8/31/2010
slice这里更好。s.slice(0, -4)
15赞 Mahn 8/11/2012
或者:s.slice(0, -“_bar”.length)(如果不想对字符数进行硬编码,则很有用)
4赞 Mike Graf 7/23/2013
我喜欢这个,因为他也帮助替换了指定的结局。
1赞 O Genthe 6/9/2021
第二个示例仅在字符串中有多个实例时删除“_bar”的第一个实例
3赞 Matthew Flaschen 8/30/2010 #9
if(str.substring(str.length - 4) == "_bar")
{
    str = str.substring(0, str.length - 4);
}
26赞 w35l3y 8/30/2010 #10

正则表达式就是你要找的:

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

评论

1赞 Aaron 6/19/2018
这解决了有条件删除而不是盲目截断的相关问题
180赞 Tim Down 8/30/2010 #11

最简单的方法是使用字符串的方法,它允许负位置(对应于字符串末尾的偏移量):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);

-2赞 kamal 12/27/2012 #12

试试这个:

<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/informativejavascript/F7WTn/87/ 上尝试实时工作示例。

评论

3赞 Albert 12/28/2012
谢谢卡迈勒。但是,我已将上面的答案标记为已接受,以满足我的需求。请注意上面的绿色复选标记。不过,我确实检查了你的代码。:)现在,在我的情况下,我只知道常见的结束字符序列。最好从字符串的末尾开始检查。如果我有一个看起来像“foo_b_bar”的字符串,你的建议就会失败,而我只想去掉最后一个“_bar”。谢谢!在两年多前提出一个问题,今天仍然收到答案,这是一次非常有趣的经历。:)
10赞 sites 12/28/2012 #13

1.,多次捕获任何角色:(.*)

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

2. ,匹配最后一个字符,在本例中:.

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

3. ,匹配字符串的末尾:$

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

评论

9赞 QueueHammer 6/21/2013
我喜欢这个,因为尽管有 .splice(),您还是找到了一种使用正则表达式的方法。
2赞 Sebastian Simon 5/14/2020
除了无法识别 Unicode 之外,这也与换行符不匹配。
15赞 Somwang Souksavatd 8/29/2013 #14

试试这个:

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

33赞 Akshay Joshi 2/27/2014 #15

使用 JavaScript 的 slice 函数:

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

这可用于删除任何长度的字符串末尾的“_bar”。

7赞 uofc 5/27/2014 #16
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
12赞 Marc477 7/29/2015 #17

使用正则表达式:

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

评论

0赞 Sebastian Simon 5/14/2020
除了无法识别 Unicode 之外,这也与换行符不匹配。
13赞 profile_-1 1/16/2016 #18

https://stackoverflow.com/questions/34817546/javascript-how-to-delete-last-two-characters-in-a-string

如果您不想要空间,只需使用修剪

"11.01 °C".slice(0,-2).trim()
1赞 bestafubana 8/20/2016 #19

如果你想删除靠近字符串末尾的东西(如果是可变大小的字符串),你可以结合 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);
8赞 Mark Walters 3/13/2018 #20

这是一个我认为我在其他答案中没有看到的替代方案,只是为了好玩。

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

不像切片或子字符串那样清晰或简单,但确实允许您使用一些不错的数组方法来玩字符串,因此值得了解。

14赞 Kamil Kiełczewski 5/13/2020 #21

性能

今天 2020.05.13 我在 MacOs High Sierra v10.13.6 上的 Chrome v81.0、Safari v13.1 和 Firefox v76.0 上对所选解决方案进行了测试。

结论

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

enter image description here

我对解决方案 ABCD、E(EXT)、F、G(MY) 执行两个测试

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

解决方案在下面的代码片段中介绍

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 短字符串的示例结果

enter image description here

42赞 Sebastian Simon 5/14/2020 #22

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

前面的答案都不是 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"

此外,如旧答案中建议的那样,方法与末尾的换行符不匹配:RegExp

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

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


使用字符串迭代器循环访问字符

Unicode 感知代码利用字符串的迭代器;请参阅 Array.from... spreadstring[Symbol.iterator] 也可以使用(例如代替 )。string

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

例子:

const string = "ẞ🦊";

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

suRegExp

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) 组成。 在这里,甚至会将其分为四个“字符”。 使用 RegExp set notation and properties of strings 提案,可以更轻松地匹配这些内容。🏳️‍🌈🏳🌈Array.from

评论

1赞 alex 6/22/2022
谢谢你的解释。事实上,它拓宽了视野。
1赞 shreyasm-dev 9/9/2020 #23

事实上,您可以使用 删除数组的最后一项,如果数组长度为 5,则将删除最后 3 项。arr.length - 2arr.length = 2

可悲的是,这不适用于字符串,但我们可以使用拆分字符串,然后在进行任何修改后连接字符串。split()join()

var str = 'string'

String.prototype.removeLast = function(n) {
  var string = this.split('')
  string.length = string.length - n

  return string.join('')
}

console.log(str.removeLast(3))

2赞 fruitloaf 10/29/2020 #24

Via slice(indexStart, indexEnd) 方法 - 注意,这不会更改现有字符串,它会创建一个副本并更改副本。

console.clear();
let str = "12345.00";
let a = str.slice(0, str.length -1)
console.log(a, "<= a");
console.log(str, "<= str is NOT changed");

通过正则表达式方法 - 注意,这不会更改现有字符串,它会创建一个副本并更改副本。

console.clear();
let regExp = /.$/g
let b = str.replace(regExp,"")
console.log(b, "<= b");
console.log(str, "<= str is NOT changed");

通过 array.splice() 方法 -> 这仅适用于数组,并且它会更改现有数组(因此要小心),您需要先将字符串转换为数组,然后再返回。

console.clear();
let str = "12345.00";
let strToArray = str.split("")
console.log(strToArray, "<= strToArray");
let spliceMethod = strToArray.splice(str.length-1, 1)
str = strToArray.join("")
console.log(str, "<= str is changed now");
-1赞 Ali Yaghoubi 10/14/2021 #25

尝试使用toFixed

const str = "12345.00";
return (+str).toFixed(1);