kết thúc với JavaScript


1103

Làm cách nào để kiểm tra xem một chuỗi kết thúc bằng một ký tự cụ thể trong JavaScript?

Ví dụ: Tôi có một chuỗi

var str = "mystring#";

Tôi muốn biết nếu chuỗi đó kết thúc với #. Làm thế nào tôi có thể kiểm tra nó?

  1. Có một endsWith()phương pháp trong JavaScript?

  2. Một giải pháp tôi có là lấy độ dài của chuỗi và lấy ký tự cuối cùng và kiểm tra nó.

Đây là cách tốt nhất hay còn cách nào khác?


5
Đây phải là một câu hỏi liên quan: stackoverflow.com/questions/646628/javascript-startswith
Hamish Grubijan

Câu trả lời:


1764

CẬP NHẬT (ngày 24 tháng 11 năm 2015):

Câu trả lời này ban đầu được đăng vào năm 2010 (SIX năm trở lại.) Vì vậy xin vui lòng lưu ý những nhận xét sâu sắc này:


TRẢ LỜI GỐC:

Tôi biết đây là một câu hỏi cũ ... nhưng tôi cũng cần câu hỏi này và tôi cần nó để hoạt động trên nhiều trình duyệt vì vậy ... kết hợp câu trả lời và nhận xét của mọi người và đơn giản hóa nó một chút:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Không tạo chuỗi con
  • Sử dụng indexOfchức năng gốc để có kết quả nhanh nhất
  • Bỏ qua các so sánh không cần thiết bằng cách sử dụng tham số thứ hai của indexOfbỏ qua phía trước
  • Hoạt động trong Internet Explorer
  • KHÔNG có biến chứng Regex

Ngoài ra, nếu bạn không thích nhét mọi thứ vào các nguyên mẫu của cấu trúc dữ liệu gốc, thì đây là phiên bản độc lập:

function endsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

EDIT: Như đã lưu ý bởi @hamish trong các bình luận, nếu bạn muốn sai sót về mặt an toàn và kiểm tra xem việc triển khai đã được cung cấp chưa, bạn chỉ cần thêm một typeofkiểm tra như vậy:

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

42
Cập nhật cho nhân viên Google - Có vẻ như ECMA6 thêm chức năng này. Bài báo MDN cũng cho thấy một polyfill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Khăn

2
@ lukas.pukenis nó bỏ qua đến cuối và chỉ kiểm tra một trường hợp của hậu tố ở cuối. không có vấn đề gì nếu chuỗi tìm kiếm xuất hiện ở nơi khác.
chakrit

3
Thêm kiểm tra cho tình huống khi đối số "hậu tố" không được xác định ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (hậu tố) {return this.indexOf (hậu tố , this.length - ((hậu tố && hậu tố.length) || 0))! == -1;};}
Mandeep

2
Các biến chứng regex bạn đã đề cập là gì?
IcedDante

5
Tạo các chuỗi con không tốn kém trên các trình duyệt hiện đại; nó có thể đã được vào năm 2010 khi câu trả lời này được đăng. Ngày nay, this.substr(-suffix.length) === suffixcách tiếp cận đơn giản là nhanh nhất trên Chrome, tương tự trên IE11 indexOfvà chỉ chậm hơn 4% (lãnh thổ fergetaboutit) trên Firefox: jsperf.com/endswith-stackoverflow/14 Và nhanh hơn trên bảng khi kết quả sai: jsperf .com / endswith-stackoverflow-when-false Tất nhiên, với việc thêm ES6 endsWith, điểm chính là moot. :-)
TJ Crowder

295
/#$/.test(str)

sẽ hoạt động trên tất cả các trình duyệt, không yêu cầu vá khỉ Stringvà không yêu cầu quét toàn bộ chuỗi như lastIndexOfkhi không có kết quả khớp.

Nếu bạn muốn khớp một chuỗi hằng có thể chứa các ký tự đặc biệt biểu thức chính quy, chẳng hạn như '$', thì bạn có thể sử dụng như sau:

function makeSuffixRegExp(suffix, caseInsensitive) {
  return new RegExp(
      String(suffix).replace(/[$%()*+.?\[\\\]{|}]/g, "\\$&") + "$",
      caseInsensitive ? "i" : "");
}

và sau đó bạn có thể sử dụng nó như thế này

makeSuffixRegExp("a[complicated]*suffix*").test(str)

10
Điều này thật hay và đơn giản nếu bạn đang kiểm tra một chuỗi con không đổi.
Warren Blanchet

1
last IndexOf quét tất cả các chuỗi? Tôi nghĩ rằng nó sẽ tìm kiếm từ cuối đến cầu xin.
Tom Brito

3
@TomBrito, chỉ lastIndexOfquét toàn bộ chuỗi nếu nó không tìm thấy kết quả khớp hoặc tìm thấy kết quả khớp ngay từ đầu. Nếu có một trận đấu ở cuối thì nó hoạt động tỷ lệ thuận với độ dài của hậu tố. Có, /asdf$/.test(str)mang lại sự thật khi strkết thúc với "asdf".
Mike Samuel

3
@Tom Brito, Đó là một biểu thức chính quy. Cú pháp được mượn từ Perl. Xem developer.mozilla.org/en/Core_JavaScript_1.5_Guide/ , hoặc để biết mức độ chi tiết không cần thiết, xem phần 7.8.5 của đặc tả ngôn ngữ EcmaScript.
Mike Samuel

2
+1 cho khả năng tương thích trình duyệt chéo. Đã thử nghiệm trên Chrome 28.0.1500.72 m, Firefox 22.0 và IE9.
Adrien Be

91
  1. Không may măn.
  2. if( "mystring#".substr(-1) === "#" ) {}

14
@Anthony, um ... vậy hãy sử dụng .Lipse-1, có vấn đề gì vậy? if (mystring.substr (mystring.length-1) === "#") {} chỉ hoạt động tốt trong IE.
BrainSlugs83

12
@ BrainSlugs83 - đó chính xác là vấn đề: cú pháp '.length-1' hoạt động trong IE và cú pháp '-1' thì không. Đó là điều cần lưu ý, vì vậy hãy +1 cho Anthony tiền boa.
avramov

2
Bạn không thể sử dụng slice()? Nó hoạt động với tôi trong thử nghiệm IE7 nhanh chóng của tôi.
alex

freaken IE. khi nào nó sẽ chết
ahnbizcad

67

Thôi nào, đây là cách endsWiththực hiện đúng :

String.prototype.endsWith = function (s) {
  return this.length >= s.length && this.substr(this.length - s.length) == s;
}

sử dụng lastIndexOfchỉ tạo ra các vòng CPU không cần thiết nếu không có kết quả khớp.


2
Đã đồng ý. Tôi thực sự cảm thấy đây là giải pháp hiệu quả nhất được cung cấp vì nó đã hủy bỏ sớm / kiểm tra độ tỉnh táo, ngắn gọn và súc tích, thanh lịch (làm quá tải nguyên mẫu chuỗi) và chuỗi con có vẻ như ít bị ảnh hưởng hơn so với quay vòng của công cụ regex.
BrainSlugs83

Cũng thích giải pháp này. Chỉ cần tên chức năng là sai chính tả. Nên là "kết thúc".
xmedeko

3
@ BrainSlugs83 Đã một vài năm, nhưng bây giờ phương pháp này không nhanh hơn phương pháp 'indexOf' được đề cập ở trên bởi chakrit, và trong Safari, nó chậm hơn 30%! Dưới đây là bài kiểm tra jsPerf cho trường hợp thất bại với chuỗi 50 ký tự: jsperf.com/endswithcomparison
Brent Faust

4
Có lẽ nên sử dụng ===mặc dù.
Timmmm

56

Phiên bản này tránh việc tạo một chuỗi con và không sử dụng các biểu thức thông thường (một số câu trả lời regex ở đây sẽ hoạt động; một số khác bị hỏng):

String.prototype.endsWith = function(str)
{
    var lastIndex = this.lastIndexOf(str);
    return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}

Nếu hiệu suất là quan trọng đối với bạn, nó sẽ đáng để kiểm tra xem lastIndexOfcó thực sự nhanh hơn việc tạo một chuỗi con hay không. (Nó có thể phụ thuộc vào công cụ JS mà bạn đang sử dụng ...) Nó có thể nhanh hơn trong trường hợp khớp và khi chuỗi nhỏ - nhưng khi chuỗi lớn, nó cần phải nhìn lại toàn bộ mặc dù chúng tôi không thực sự quan tâm :(

Để kiểm tra một ký tự đơn, tìm độ dài và sau đó sử dụng charAtcó lẽ là cách tốt nhất.


2
Nếu this.lastIndexOf () trả về -1, bạn có thể gặp các trường hợp trong đó nó trả về sự phụ thuộc thực sự vào this.length và str.length. Thêm một bài kiểm tra mà Last IndexOf ()! = -1.
ebruchez

1
Tại sao phương thức regex bị hỏng?
izb

2
@izb: Các câu trả lời cũ hơn của tôi mà cố gắng sử dụng str+"$"làm biểu thức chính quy bị hỏng, vì chúng có thể không phải là biểu thức chính thức hợp lệ.
Jon Skeet

26

Không thấy apporach với slicephương pháp. Vì vậy, tôi chỉ để nó ở đây:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}

1
Bạn có thể đơn giản hóa nó thêm một chút: return str.slice (-1) === hậu tố;
Erik K.

2
Đây là câu trả lời tốt nhất. Không chắc chắn tại sao nó không có nhiều upvote.
hạt nhân

17
return this.lastIndexOf(str) + str.length == this.length;

không hoạt động trong trường hợp độ dài chuỗi gốc nhỏ hơn độ dài chuỗi tìm kiếm và không tìm thấy chuỗi tìm kiếm:

lastIndexOf trả về -1, sau đó bạn thêm độ dài chuỗi tìm kiếm và bạn còn lại với độ dài của chuỗi gốc.

Một sửa chữa có thể là

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length

30
Bạn đã kiếm được một số lỗi Tìm thấy trong một huy hiệu Jon Skeet trả lời. Xem hồ sơ của bạn để biết chi tiết.
bobince

17

Từ developer.mozilla.org String.prototype.endsWith ()

Tóm lược

Các endsWith()phương pháp xác định liệu một chuỗi đầu với các ký tự của một chuỗi, trở về đúng hay sai khi thích hợp.

Cú pháp

str.endsWith(searchString [, position]);

Thông số

  • searchString : Các ký tự được tìm kiếm ở cuối chuỗi này.

  • vị trí : Tìm kiếm trong chuỗi này như thể chuỗi này chỉ dài như vậy; mặc định cho độ dài thực tế của chuỗi này, được kẹp trong phạm vi được thiết lập bởi độ dài của chuỗi này.

Sự miêu tả

Phương pháp này cho phép bạn xác định xem một chuỗi có kết thúc bằng một chuỗi khác hay không.

Ví dụ

var str = "To be, or not to be, that is the question.";

alert( str.endsWith("question.") );  // true
alert( str.endsWith("to be") );      // false
alert( str.endsWith("to be", 19) );  // true

Thông số kỹ thuật

Đặc tả ngôn ngữ ECMAScript Phiên bản thứ 6 (ECMA-262)

Tính tương thích của trình duyệt web

Tính tương thích của trình duyệt web


10
if( ("mystring#").substr(-1,1) == '#' )

-- Hoặc là --

if( ("mystring#").match(/#$/) )

8
String.prototype.endsWith = function(str) 
{return (this.match(str+"$")==str)}

String.prototype.startsWith = function(str) 
{return (this.match("^"+str)==str)}

Tôi hi vọng cái này giúp được

var myStr =   Earth is a beautiful planet  ”;
var myStr2 = myStr.trim();  
//==“Earth is a beautiful planet”;

if (myStr2.startsWith(“Earth”)) // returns TRUE

if (myStr2.endsWith(“planet”)) // returns TRUE

if (myStr.startsWith(“Earth”)) 
// returns FALSE due to the leading spaces…

if (myStr.endsWith(“planet”)) 
// returns FALSE due to trailing spaces…

cách truyền thống

function strStartsWith(str, prefix) {
    return str.indexOf(prefix) === 0;
}

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}

Bạn phải thoát chuỗi của mình cho chuỗi thoát regex
Juan Mendes

1
Biểu thức thông thường là chậm ngay cả trong các ngôn ngữ nhanh. Chỉ cần kiểm tra kết thúc của một chuỗi.
Daniel Nuriyev

8

Tôi không biết về bạn, nhưng:

var s = "mystring#";
s.length >= 1 && s[s.length - 1] == '#'; // will do the thing!

Tại sao biểu thức chính quy? Tại sao phải lộn xộn với nguyên mẫu? chất nền? xin chào ...


'cus đôi khi sẽ tốt hơn khi WET
Martin Capodici

8

Chỉ là một sự thay thế nhanh chóng khác có tác dụng như một cơ duyên đối với tôi, sử dụng regex:

// Would be equivalent to:
// "Hello World!".endsWith("World!")
"Hello World!".match("World!$") != null


6

Tôi vừa tìm hiểu về thư viện chuỗi này:

http://opesjs.com/

Bao gồm tệp js và sau đó sử dụng Sbiến như thế này:

S('hi there').endsWith('hi there')

Nó cũng có thể được sử dụng trong NodeJS bằng cách cài đặt nó:

npm install string

Sau đó yêu cầu nó là Sbiến:

var S = require('string');

Trang web cũng có các liên kết đến các thư viện chuỗi thay thế, nếu thư viện này không thích bạn.


4
function strEndsWith(str,suffix) {
  var reguex= new RegExp(suffix+'$');

  if (str.match(reguex)!=null)
      return true;

  return false;
}

1
Sẽ tốt hơn nếu bạn giải thích lý do tại sao mã của bạn giải quyết vấn đề. Xem hướng dẫn Cách trả lời .
brasofilo

đối số hậu tố nên được quét cho các biểu thức regex phải được thoát. sử dụng indexOf hoặc lastIndexOf dường như là một lựa chọn tốt hơn.
vlad_tepesch

Sẽ không hoạt động nếu hậu tố chứa bất kỳ ký tự nào trong số này :. * +? ^ = !: $ {} () [] / \
gtournie

4

Rất nhiều điều cho một vấn đề nhỏ như vậy, chỉ cần sử dụng Biểu thức chính quy này

var str = "mystring#";
var regex = /^.*#$/

if (regex.test(str)){
  //if it has a trailing '#'
}


4

Nó đã được nhiều năm cho câu hỏi này. Hãy để tôi thêm một bản cập nhật quan trọng cho những người dùng muốn sử dụng câu trả lời được bình chọn nhiều nhất.

Các hàm 'endWith' đã được thêm vào JavaScript như một phần của ECMAScript 6 (công nghệ thử nghiệm)

Tham khảo tại đây: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Do đó, rất nên thêm kiểm tra cho sự tồn tại của việc thực hiện riêng như được đề cập trong câu trả lời.


2
function check(str)
{
    var lastIndex = str.lastIndexOf('/');
    return (lastIndex != -1) && (lastIndex  == (str.length - 1));
}

2

Một cách để chứng minh trong tương lai và / hoặc ngăn chặn việc ghi đè lên nguyên mẫu hiện tại sẽ là kiểm tra thử xem nó đã được thêm vào nguyên mẫu Chuỗi chưa. Đây là của tôi về phiên bản không được đánh giá cao regex.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

Sử dụng if (!String.prototype.hasOwnProperty("endsWith"))là cách tốt nhất. Với typeof"MooTools và một số thư viện AJAX khác sẽ làm bạn khó chịu", theo "Crockford trên JavaScript - Cấp 7: ECMAScript 5: Các bộ phận mới", lúc 15:50 phút.
XP1

2

Câu trả lời được chấp nhận của @ chakrit là một cách vững chắc để tự làm điều đó. Tuy nhiên, nếu bạn đang tìm kiếm một giải pháp đóng gói, tôi khuyên bạn nên xem underscore.opes , như @mlunoe chỉ ra. Sử dụng underscore.opes, mã sẽ là:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}

1

nếu bạn không muốn sử dụng lasIndexOf hoặc chất nền thì tại sao không chỉ nhìn vào chuỗi ở trạng thái tự nhiên của nó (ví dụ: một mảng)

String.prototype.endsWith = function(suffix) {
    if (this[this.length - 1] == suffix) return true;
    return false;
}

hoặc như một chức năng độc lập

function strEndsWith(str,suffix) {
    if (str[str.length - 1] == suffix) return true;
    return false;
}

1
String.prototype.endWith = function (a) {
    var isExp = a.constructor.name === "RegExp",
    val = this;
    if (isExp === false) {
        a = escape(a);
        val = escape(val);
    } else
        a = a.toString().replace(/(^\/)|(\/$)/g, "");
    return eval("/" + a + "$/.test(val)");
}

// example
var str = "Hello";
alert(str.endWith("lo"));
alert(str.endWith(/l(o|a)/));

1

Sau tất cả những câu trả lời dài, tôi thấy đoạn mã này đơn giản và dễ hiểu!

function end(str, target) {
  return str.substr(-target.length) == target;
}

1

Đây là việc thực hiện kết thúc với: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }


1

Đây là việc thực hiện endsWith:

String.prototype.endsWith = function (str) {
  return (this.length >= str.length) && (this.substr(this.length - str.length) === str);
}

0

Điều này được xây dựng dựa trên câu trả lời được chấp nhận của @ charkit cho phép Mảng chuỗi hoặc chuỗi được truyền vào dưới dạng đối số.

if (typeof String.prototype.endsWith === 'undefined') {
    String.prototype.endsWith = function(suffix) {
        if (typeof suffix === 'String') {
            return this.indexOf(suffix, this.length - suffix.length) !== -1;
        }else if(suffix instanceof Array){
            return _.find(suffix, function(value){
                console.log(value, (this.indexOf(value, this.length - value.length) !== -1));
                return this.indexOf(value, this.length - value.length) !== -1;
            }, this);
        }
    };
}

Điều này đòi hỏi dấu gạch dưới - nhưng có lẽ có thể được điều chỉnh để loại bỏ sự phụ thuộc gạch dưới.


1
Đây là một giải pháp tồi, thay vì nếu bạn đã sử dụng dấu gạch dưới, bạn nên thêm epeli.github.io/underscore.opes vào phần phụ thuộc của mình và sử dụng triển khai của chúng:_.str.endsWith
mlunoe 23/12/14

0
if(typeof String.prototype.endsWith !== "function") {
    /**
     * String.prototype.endsWith
     * Check if given string locate at the end of current string
     * @param {string} substring substring to locate in the current string.
     * @param {number=} position end the endsWith check at that position
     * @return {boolean}
     *
     * @edition ECMA-262 6th Edition, 15.5.4.23
     */
    String.prototype.endsWith = function(substring, position) {
        substring = String(substring);

        var subLen = substring.length | 0;

        if( !subLen )return true;//Empty string

        var strLen = this.length;

        if( position === void 0 )position = strLen;
        else position = position | 0;

        if( position < 1 )return false;

        var fromIndex = (strLen < position ? strLen : position) - subLen;

        return (fromIndex >= 0 || subLen === -fromIndex)
            && (
                position === 0
                // if position not at the and of the string, we can optimise search substring
                //  by checking first symbol of substring exists in search position in current string
                || this.charCodeAt(fromIndex) === substring.charCodeAt(0)//fast false
            )
            && this.indexOf(substring, fromIndex) === fromIndex
        ;
    };
}

Những lợi ích:

  • Phiên bản này không chỉ sử dụng lại indexOf.
  • Hiệu suất lớn nhất trên chuỗi dài. Dưới đây là bài kiểm tra tốc độ http://jsperf.com/starts-ends-with/4
  • Hoàn toàn tương thích với đặc điểm kỹ thuật ecmascript. Nó vượt qua các bài kiểm tra

0

Không sử dụng biểu thức thông thường. Chúng chậm ngay cả trong các ngôn ngữ nhanh. Chỉ cần viết một hàm kiểm tra kết thúc của một chuỗi. Thư viện này có các ví dụ hay: groundjs / produc.js . Hãy cẩn thận khi thêm một hàm vào String.prototype. Mã này có các ví dụ hay về cách thực hiện: groundjs /otype.js Nói chung, đây là một thư viện cấp độ ngôn ngữ đẹp: groundjs Bạn cũng có thể xem qua lodash


0

tất cả chúng đều là những ví dụ rất hữu ích Việc thêm String.prototype.endsWith = function(str)sẽ giúp chúng ta chỉ cần gọi phương thức để kiểm tra xem chuỗi của chúng ta có kết thúc với nó hay không, regrec cũng sẽ làm điều đó.

Tôi tìm thấy một giải pháp tốt hơn của tôi. Cảm ơn mọi người.


0

Đối với cà phê

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
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.