JavaScript chặt / cắt / cắt bỏ ký tự cuối cùng trong chuỗi


1974

Tôi có một chuỗi, 12345.00và tôi muốn nó trở lại 12345.0.

Tôi đã xem xét trim, nhưng có vẻ như nó chỉ cắt xén khoảng trắng và slicetôi không thấy nó sẽ hoạt động như thế nào. Bất kỳ đề xuất?


36
Bạn có quan tâm đến làm tròn? 12345.46 = 12345.5 hay 12345.4?
RSolberg

9
Bạn có biết hậu tố là gì hoặc bạn muốn tách và loại bỏ từ cuối cùng dựa trên dấu gạch dưới của bạn?
Cᴏʀʏ

65
Ho ho ho, @RSolberg: bạn không thể làm tròn một chuỗi!
Ziggy

50
@Ziggy nói gì? Math.round('0.5') === 1;)
TWiStErRob

16
@TWiStErRob Oh JavaScript, tôi sẽ làm gì với bạn? * lắc đầu *
Chuck Le Mông

Câu trả lời:


3214

Bạn có thể sử dụng chức năng chuỗi con :

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

Đây là câu trả lời được chấp nhận, nhưng theo các cuộc hội thoại dưới đây, cú pháp lát rõ ràng hơn nhiều:

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


23
@Kheu - ký hiệu lát cắt sạch hơn nhiều đối với tôi. Trước đây tôi đã sử dụng phiên bản chuỗi con. Cảm ơn!
Matt Ball

32
Hãy tha thứ cho tôi nếu tôi sai nhưng bạn không cần gán giá trị của str.sub chuỗi cho str nữa chứ? Thíchstr = str.substring(0, str.length -1);
Doug Molineux

10
Các phương thức slice& substringđều giống nhau; ngoại trừ việc slice()chấp nhận một chỉ số âm, liên quan đến cuối chuỗi, nhưng không phải là lỗi substring, nó sẽ out-of-boundgây ra lỗi
Amol M Kulkarni

20
Trong trường hợp bất cứ ai đang tự hỏi, substringlà nhanh hơn 11% slice. jsperf.com/js-slice-vs-substring-test
BenR

19
chuỗi con là tối ưu hóa vi mô điên rồ mà tôi không nghĩ bạn nên làm. Tối đa hóa cho khả năng đọc đầu tiên. Sau đó tối ưu hóa quả treo thấp nếu cần.
Alfred

1306

Bạn có thể sử dụng lát ! Bạn chỉ cần chắc chắn rằng bạn biết cách sử dụng nó. Số dương có liên quan đến đầu, số âm có liên quan đến cuối.

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

75
So với giải pháp được chấp nhận, đây là cách thanh lịch hơn và có thể được sử dụng ngay cả với các chuỗi được tạo động
Sameer Alibhai

1
Tôi thích cách này vì nó sống với tư duy php cho chức năng cơ bản, dễ nhớ và dễ viết hơn.
tìm đường

2
@SameerAlibhai Tôi đồng ý với bạn, nhưng không substringthể sử dụng phương thức này trên các chuỗi động? Bằng cách sử dụng str.length để tự động lấy chiều dài?
Doug Molineux

Nên thêm rằng chỉ số đầu tiên là bao gồm và độc quyền thứ hai.
Linh tinh 7/07/2015

@KevinBeal bạn chỉ có thể sử dụng F12 trong các trình duyệt chính và nhập nó vào Bảng điều khiển, hoạt động trên bất kỳ trang nào và thậm chí bạn có ngữ cảnh và có thể tải thư viện.
TWiStErRob

263

Bạn có thể sử dụng phương thức chuỗi con của các đối tượng chuỗi JavaScript:

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

Nó vô điều kiện loại bỏ bốn ký tự cuối cùng khỏi chuỗi s.

Tuy nhiên, nếu bạn muốn loại bỏ có điều kiện bốn ký tự cuối cùng, chỉ khi chúng chính xác _bar :

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

107
sliceở đây tốt hơn s.slice(0, -4)
Tim Down

12
Ngoài ra: s.slice (0, - "_ bar" .length) (hữu ích nếu người ta không muốn mã hóa số lượng ký tự)
Mahn

3
Tôi thích cái này vì anh ấy cũng giúp đỡ để thay thế một kết thúc được chỉ định.
Mike Graf

162

Phương pháp đơn giản nhất là sử dụng slicephương thức của chuỗi, cho phép các vị trí âm (tương ứng với độ lệch từ cuối chuỗi):

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

Nếu bạn cần một cái gì đó tổng quát hơn để loại bỏ mọi thứ sau (và bao gồm) dấu gạch dưới cuối cùng, bạn có thể thực hiện các thao tác sau (miễn là sđược đảm bảo có ít nhất một dấu gạch dưới):

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


67

Đối với một số như ví dụ của bạn, tôi khuyên bạn nên làm điều này hơn substring:

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

Xin lưu ý rằng điều này thực sự sẽ làm tròn số, mặc dù, điều mà tôi tưởng tượng là mong muốn nhưng có thể không:

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


11
+1 Đây là những gì OP cần, hãy quên giả định sai rằng có các chuỗi được cắt bớt.
naugtur

2
Đó không phải là một giả định sai lầm, OP nói về chuỗi. Của bạn là một giả định sai lầm vì OP không nói về làm tròn số.
Fernando

30

Sử dụng hàm lát cắt của JavaScript:

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

Điều này có thể được sử dụng để xóa '_bar' ở cuối chuỗi, có độ dài bất kỳ.


19

Một biểu thức chính quy là những gì bạn đang tìm kiếm:

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


Giải pháp của bạn hiệu quả, nhưng câu trả lời của Alex toàn diện hơn. Vì vậy, tôi sẽ chấp nhận anh ấy. Cảm ơn!
Albert

1
Điều này giải quyết một vấn đề liên quan của việc loại bỏ có điều kiện thay vì cắt cụt một cách mù quáng
Aaron



9

Sử dụng regex:

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


Ngoài việc không nhận biết Unicode, điều này cũng không khớp với ngắt dòng.
dùng4642212

7
  1. (. *), chụp bất kỳ nhân vật nào nhiều lần

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

  1. ., khớp với ký tự cuối cùng, trong trường hợp này

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

  1. $, khớp với phần cuối của chuỗi

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


9
Tôi thích điều này bởi vì mặc dù .splice () bạn đã tìm thấy một cách để sử dụng biểu thức chính quy.
Queue Hammer

Ngoài việc không nhận biết Unicode, điều này cũng không khớp với ngắt dòng.
dùng4642212


5

Đây là một thay thế mà tôi không nghĩ rằng tôi đã thấy trong các câu trả lời khác, chỉ để cho vui.

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

Không dễ đọc hoặc đơn giản như lát hoặc chuỗi con nhưng không cho phép bạn chơi với chuỗi bằng một số phương thức mảng đẹp, rất đáng để biết.


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

Con đường ngắn nhất:

str.slice(0, -1); 

3

Nếu bạn muốn làm tròn số phao chung, thay vì chỉ cắt bớt ký tự cuối cùng:

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: Có vẻ như tồn tại một chức năng được xây dựng cho việc này, như Paolo chỉ ra. Giải pháp đó rõ ràng là sạch hơn tôi nhiều. Sử dụng parseFloat theo sau là toFixed




1

Hiệu suất

Hôm nay 2020.05.13 Tôi thực hiện kiểm tra các giải pháp được chọn trên Chrome v81.0, Safari v13.1 và Firefox v76.0 trên MacOs High Sierra v10.13.6.

Kết luận

  • các slice(0,-1) (D) là nhanh hay giải pháp nhanh nhất cho các chuỗi ngắn hạn và dài và nó được khuyến cáo như là giải pháp qua trình duyệt nhanh
  • giải pháp dựa trên substring(C) vàsubstr (E) là nhanh chóng
  • các giải pháp dựa trên biểu thức chính quy (A, B) là chậm / trung bình nhanh
  • các giải pháp B, F và G chậm cho các chuỗi dài
  • giải pháp F chậm nhất đối với chuỗi ngắn, G chậm nhất đối với chuỗi dài

nhập mô tả hình ảnh ở đây

Chi tiết

Tôi thực hiện hai bài kiểm tra cho các giải pháp A , B , C , D , E ( ext ), F , G (my)

  • cho chuỗi ngắn 8 ký tự (từ câu hỏi OP) - bạn có thể chạy nó TẠI ĐÂY
  • cho chuỗi dài 1M - bạn có thể chạy nó TẠI ĐÂY

Các giải pháp được trình bày trong đoạn trích dưới đây

Dưới đây là kết quả ví dụ cho Chrome cho chuỗi ngắn

nhập mô tả hình ảnh ở đây


1

Xin lưu ý rằng String.prototype.{ split, slice, substr, substring }hoạt động trên các chuỗi được mã hóa UTF-16

Không có câu trả lời nào trước đây là nhận thức về Unicode. Các chuỗi được mã hóa dưới dạng UTF-16 trong hầu hết các công cụ JavaScript hiện đại, nhưng các điểm mã Unicode cao hơn yêu cầu các cặp thay thế , vì vậy các phương thức chuỗi cũ hơn, hoạt động trên các đơn vị mã UTF-16, không phải các điểm mã 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"

Ngoài ra, các câu trả lời RegExp không khớp dòng ngắt ở cuối ở dạng hiện tại của chúng:

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

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


Sử dụng chuỗi lặp để lặp các ký tự

Mã nhận biết Unicode sử dụng trình vòng lặp của chuỗi; nhìn thấy Array.from...lan rộng . string[Symbol.iterator]có thể được sử dụng (ví dụ thay vìstring ) là tốt.

Xem thêm Cách chia chuỗi Unicode thành các ký tự trong JavaScript .

Ví dụ:

const string = "ẞ🦊";

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

Sử dụng sucờ trên mộtRegExp

Các dotAllhoặc scờ làm cho .ký tự ngắt dòng phù hợp, các unicodehoặc ucờ cho phép một số tính năng Unicode liên quan.

Ví dụ:

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


Lưu ý rằng một số biểu đồ bao gồm nhiều hơn một điểm mã, ví dụ 🏳️‍🌈bao gồm chuỗi 🏳(U + 1F3F3), VS16(U + FE0F) , ZWJ(U + 200D) , 🌈(U + 1F308). Ở đây, thậm chí Array.fromsẽ chia thành bốn nhân vật khác. Có thể phù hợp với các thuộc tính Unicode với đề xuất thuộc tính chuỗi thoát .


-1

Trong trường hợp bạn muốn loại bỏ thứ gì đó ở gần cuối chuỗi (trong trường hợp chuỗi có kích thước thay đổi), bạn có thể kết hợp lát () và chất nền ().

Tôi đã có một chuỗi với đánh dấu, được xây dựng động, với một danh sách các thẻ neo được phân tách bằng dấu phẩy. Chuỗi là một cái gì đó như:

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

Để xóa dấu phẩy cuối cùng tôi đã làm như sau:

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

-3

Thử cái này:

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

Bạn cũng có thể thử ví dụ làm việc trực tiếp trên http://jsfiddle.net/informativejavascript/F7WTn/87/ .


3
Cảm ơn kamal. Tuy nhiên, tôi đã đánh dấu câu trả lời ở trên là chấp nhận cho nhu cầu của mình. Lưu ý dấu kiểm màu xanh lá cây ở trên. Mặc dù, tôi đã kiểm tra mã của bạn. :) Bây giờ, trong tình huống của tôi, tôi chỉ biết chuỗi ký tự kết thúc chung. Sẽ tốt hơn nếu chỉ bắt đầu kiểm tra từ cuối chuỗi. Đề xuất của bạn sẽ thất bại nếu tôi có một chuỗi trông giống như "foo_b_bar" và tôi chỉ muốn lấy ra "_bar" cuối cùng. Cảm ơn mặc dù! Đây là một trải nghiệm khá thú vị khi đặt câu hỏi hơn 2 năm trước và vẫn nhận được câu trả lời cho ngày hôm nay. :)
Albert

-4

@Jonon S:

Bạn có thể sử dụng lát! Bạn chỉ cần chắc chắn rằng bạn biết cách sử dụng nó. Số dương có liên quan đến đầu, số âm có liên quan đến cuối.

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

Xin lỗi vì đồ thị của tôi nhưng bài đăng đã được gắn thẻ 'jquery' trước đó. Vì vậy, bạn không thể sử dụng lát () bên trong jQuery vì lát () là phương thức jQuery cho các hoạt động với các phần tử DOM, không phải là chuỗi con ... Nói cách khác, câu trả lời @Jon Erickson đề xuất giải pháp thực sự hoàn hảo.

Tuy nhiên, phương thức của bạn sẽ hoạt động ngoài chức năng jQuery, bên trong Javascript đơn giản. Cần phải nói do cuộc thảo luận cuối cùng trong các bình luận, rằng jQuery là phần mở rộng của JS thường xuyên hơn rất nhiều so với ECMAScript được biết đến nhiều nhất của cha mẹ anh ấy.

Ở đây cũng tồn tại hai phương thức:

như là của chúng ta:

string.substring(from,to) as plus if 'to' index nulled trả về phần còn lại của chuỗi. vì vậy: string.substring(from) tích cực hay tiêu cực ...

và một số khác - chất nền () - cung cấp phạm vi của chuỗi con và 'độ dài' chỉ có thể dương: string.substr(start,length)

Ngoài ra, một số nhà bảo trì đề xuất rằng phương pháp cuối cùng string.substr(start,length)không hoạt động hoặc hoạt động với lỗi cho MSIE.


3
Ý anh là gì? String.prototype.slicelà một phương pháp bản địa
naugtur

nó chỉ những gì bạn nói Phương thức gốc Javascript, nhưng cũng là slice()phương thức jQuery để thao tác DOM: API jQuery: .slice () . VÀ CHẮC CHẮN, đó là CÓ THỂ ĐƯỢC TÌM KIẾM như một sự kế thừa đa hình của JS Array.slice (), nhưng đó là hai phương thức khác nhau và tôi nghĩ cần phải phân biệt nó. Vì vậy, nó chỉ là một xấp xỉ với kiến ​​thức này.
nhanh chóng

12
Nếu bạn gọi .slicemột biến là một chuỗi, nó sẽ thực hiện đúng như những gì OP muốn. Sẽ không thành vấn đề nếu nó "bên trong jQuery" và không có cách nào nó có thể "can thiệp" theo bất kỳ cách nào trừ khi bạn ghi đè lên String.prototypejQuery, điều mà tôi chắc chắn sẽ ngăn BẤT K code mã javascript nào hoạt động. Câu trả lời của bạn chỉ nói rằng câu trả lời khác là không tốt và lập luận bạn cung cấp là không chính xác.
naugtur

1
Tôi có thể đồng ý với @naugtur câu trả lời này là sai, phương thức lát của chuỗi không được thực hiện bởi jQuery.
recbot

1
Tôi nghĩ rằng điểm mà naugtur đang tạo ra chỉ là, khả thi, bạn có thể kết thúc bằng một chuỗi được bao bọc bởi một đối tượng jQuery (ví dụ: nếu bạn thực hiện một số .datathao tác ưa thích và kết thúc bằng "chuỗi" này), nếu bạn gọi slicenó, sẽ không làm những gì bạn muốn. Điều đó nói rằng, đây không thực sự là một câu trả lời hữu ích.
mAAdhaTTah

-8

Sử dụng chuỗi con để có được mọi thứ ở bên trái của _bar. Nhưng trước tiên, bạn phải có được các thanh của _bar trong chuỗi:

str.substring(3, 7);

3 là bắt đầu và 7 là chiều dài.


1
điều này chỉ hoạt động trên "foo_bar" chứ không phải trên "foo_foo_bar", câu hỏi là về một chuỗi có độ dài bất kỳ nhưng kết thúc đã biết.
Thiết kế bởi Adrian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.