JavaScript截断/切片/修剪掉字符串中的最后一个字符


1973

我有一个字符串,12345.00并且我希望它返回12345.0

我已经看过了trim,但是看起来它只是在修剪空白,slice而我看不出它是如何工作的。有什么建议么?


36
您是否舍入?12345.46 = 12345.5或12345.4?
RSolberg 2009年

9
您知道后缀是什么,还是要根据下划线拆分并删除最后一个单词?
2010年

65
呵呵呵,// @ RSolberg:你不能四舍五入
Ziggy

50
@Ziggy说什么?Math.round('0.5') === 1;)
TWiStErRob 2015年

16
@TWiStErRob哦,JavaScript,我要和你做什么?*摇头*
查乐对接

Answers:


3211

您可以使用substring函数:

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

10
slicesubstring方法都是最相同; 除了slice()接受相对于字符串结尾的负索引,而不接受相对值substring,它会引发out-of-bound错误
Amol M Kulkarni 2013年

20
如果有人想知道,substring速度比快11%slicejsperf.com/js-slice-vs-substring-test
BenR 2014年

19
substring是疯狂的微优化,我认为您不应该这样做。首先最大化可读性。然后根据需要优化低挂水果。
2014年

1306

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

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

75
与公认的解决方案相比,这是一种更优雅的方法,甚至可以用于动态创建的字符串
Sameer Alibhai 2012年

1
我喜欢这种方式,因为它与php一起思考substr函数,更容易记住和实时编写。
探路者

1
@SameerAlibhai我同意你的观点,但是该substring方法也不能用于动态字符串吗?通过使用str.length动态获取长度?
Doug Molineux 2014年

应该添加的是第一个索引是包含索引,第二个索引是排斥索引。
错误的

@KevinBeal您只可以在主流浏览器中使用F12并将其输入到控制台中,可以在任何页面上使用,甚至可以使用上下文并可以加载库。
TWiStErRob 2015年

263

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

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

它无条件删除string中的最后四个字符s

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

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

107
slice在这里更好。s.slice(0, -4)
Tim Down'8

12
或者:s.slice(0,-“ _ bar” .length)(如果不想对字符数进行硬编码很有用)
Mahn 2012年

3
我喜欢这个,因为他也为替换指定的结尾提供了帮助。
Mike Graf

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这就是OP所需要的,忘记了要修剪的字符串的错误假设。
naugtur

2
这不是一个错误的假设,OP谈到字符串。您的假设是错误的,因为OP并未讨论舍入数字。
Fernando

30

使用JavaScript的slice函数:

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$/, ""));


您的解决方案有效,但是Alex的答案更为全面。所以我会接受他的。谢谢!
艾伯特2010年

1
这解决了相关的有条件删除而不是盲目删减的问题
Aaron


9

怎么样:

let myString = "12345.00";
console.log(myString.substring(0, myString.length - 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(""));

虽然不像slice或substring那样清晰易懂,但确实允许您使用一些不错的数组方法来处理字符串,因此值得一读。


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

编辑:就像Paolo指出的那样,似乎有一个内置函数。该解决方案显然比我的解决方案干净得多。使用parseFloat,然后使用toFixed





1

性能

今天,2020.05.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对于长字符串最慢

在此处输入图片说明

细节

我对解决方案ABCD,E(ext),F,G(my)执行了两个测试

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

解决方案在下面的代码段中提供

这是短字符串的Chrome结果示例

在此处输入图片说明


0

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

先前的答案都不是支持Unicode的。在大多数现代JavaScript引擎中,字符串被编码为UTF-16,但是更高的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


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

支持Unicode的代码利用了字符串的迭代器。看到Array.from...传播string[Symbol.iterator]也可以使用(例如代替string)。

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

例子:

const string = "ẞ🦊";

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

在上使用su标志RegExp

dotAlls标志品牌.相匹配换行符,则unicodeu标志启用某些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)组成。在这里,even 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

@Jason S:

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

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

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

但是,您的方法将无法在简单的Javascript中使用jQuery函数。需要说的是,由于在评论中进行了最后的讨论,所以jQuery是JS的可更新扩展,而不是其父辈最著名的ECMAScript。

这里也存在两种方法:

作为我们的:

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

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

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


2
你什么意思?String.prototype.slice是一种本地方法
naugtur

这只是你所说的。Javascript本机方法,还有slice()用于DOM操作的jQuery 方法:jQuery API:.slice()。可以肯定的是,它可以像JS Array.slice()的多态继承一样来计算,但是它是两种不同的方法,我认为需要将其区分开。因此,这只是对这些知识的近似。
快速的2012年

11
如果您调用的.slice是字符串变量,它将按照OP的要求进行操作。没关系是在“ jQuery内部”,也没有办法以任何方式“干扰”,除非您String.prototype用jQuery 覆盖,我相信这将阻止任何javascript代码正常工作。您的答案只是说其他答案不好,您提供的论点是不正确的。
naugtur

1
我可以同意@naugtur这个答案是错误的,字符串的slice方法不受jQuery的影响。
reconbot

1
我认为,naugtur提出的观点是,可能的话,您可能会得到一个由jQuery对象包装的字符串(例如,如果您进行了一些花哨的.data操作并最终得到了这个“字符串”),那么如果您调用slice它,不会做你想要的。就是说,这实际上不是一个有用的答案。
mAadhaTTah 2016年

-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/informativejavascript/F7WTn/87/上尝试该在线示例。


3
谢谢kamal。但是,我已将上面的答案标记为满足我的需求。注意上面的绿色复选标记。不过,我确实检查了您的代码。:)现在,在我的情况下,我只知道常见的结束字符序列。最好只从字符串的末尾开始检查。如果我有一个看起来像“ foo_b_bar”的字符串,而我只想取出最后一个“ _bar”,则您的建议将失败。不过谢谢!在2年前提出一个问题,直到今天仍然能收到答案,这是非常有趣的经历。:)
Albert

-8

使用子字符串将所有内容移到_bar的左侧。但是首先您必须在字符串中获得_bar的指令:

str.substring(3, 7);

3是开始,7是长度。


1
这仅适用于“ foo_bar”而不适用于“ foo_foo_bar”,问题是关于具有已知长度的任意长度的字符串。
设计者:Adrian
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.