berakhirDengan JavaScript

1103

Bagaimana saya bisa memeriksa apakah string diakhiri dengan karakter tertentu dalam JavaScript?

Contoh: Saya punya string

var str = "mystring#";

Saya ingin tahu apakah string itu diakhiri dengan #. Bagaimana saya bisa memeriksanya?

  1. Apakah ada endsWith()metode dalam JavaScript?

  2. Salah satu solusi yang saya miliki adalah mengambil panjang string dan mendapatkan karakter terakhir dan memeriksanya.

Apakah ini cara terbaik atau ada cara lain?

Bobby Kumar
sumber
5
Ini harus menjadi pertanyaan terkait: stackoverflow.com/questions/646628/javascript-startswith
Hamish Grubijan

Jawaban:

1764

UPDATE (24 Nov 2015):

Jawaban ini awalnya diposting pada tahun 2010 (ENAM tahun yang lalu.) Jadi harap perhatikan komentar yang berwawasan luas ini:


JAWABAN ASLI:

Saya tahu ini adalah pertanyaan berumur satu tahun ... tapi saya perlu ini juga dan saya membutuhkannya untuk bekerja lintas-browser jadi ... menggabungkan jawaban dan komentar semua orang dan sedikit menyederhanakannya:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Tidak membuat substring
  • Menggunakan indexOffungsi asli untuk hasil tercepat
  • Lewati perbandingan yang tidak perlu menggunakan parameter kedua indexOfuntuk melompat ke depan
  • Bekerja di Internet Explorer
  • TIDAK ADA komplikasi Regex

Juga, jika Anda tidak suka memasukkan hal-hal dalam prototipe struktur data asli, berikut ini adalah versi mandiri:

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

EDIT: Seperti dicatat oleh @hamish di komentar, jika Anda ingin berbuat salah di sisi aman dan memeriksa apakah suatu implementasi telah disediakan, Anda bisa menambahkan typeofcek seperti:

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
chakrit
sumber
42
Pembaruan untuk Googler - Sepertinya ECMA6 menambahkan fungsi ini. Artikel MDN juga menunjukkan polyfill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Shauna
2
@ lukas.pukenis melompati sampai akhir dan hanya memeriksa satu contoh akhiran di akhir. tidak masalah jika string pencarian muncul di tempat lain.
chakrit
3
Menambahkan tanda centang untuk situasi ketika argumen "suffix" tidak didefinisikan ": if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (suffix) {mengembalikan this.indexOf (suffix , this.length - ((suffix && suffix.length) || 0))! == -1;};}
Mandeep
2
Apa komplikasi regex yang Anda rujuk?
IcedDante
5
Membuat substring tidak mahal pada browser modern; mungkin pada tahun 2010 ketika jawaban ini diposting. Saat ini, this.substr(-suffix.length) === suffixpendekatan sederhana tercepat di Chrome, sama pada IE11 indexOf, dan hanya 4% lebih lambat (wilayah fergetaboutit) di Firefox: jsperf.com/endswith-stackoverflow/14 Dan lebih cepat di papan ketika hasilnya salah: jsperf .com / endswith-stackoverflow-when-false Tentu saja, dengan menambahkan ES6 endsWith, intinya adalah moot. :-)
TJ Crowder
295
/#$/.test(str)

akan bekerja pada semua browser, tidak memerlukan patch monyet String, dan tidak memerlukan pemindaian seluruh string seperti lastIndexOfhalnya ketika tidak ada kecocokan.

Jika Anda ingin mencocokkan string konstan yang mungkin berisi karakter khusus ekspresi reguler, seperti '$', maka Anda dapat menggunakan yang berikut:

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

dan kemudian Anda bisa menggunakannya seperti ini

makeSuffixRegExp("a[complicated]*suffix*").test(str)
Mike Samuel
sumber
10
Ini bagus dan sederhana jika Anda memeriksa substring yang konstan.
Warren Blanchet
1
lastIndexOf memindai semua string? Saya pikir itu akan mencari dari akhir hingga awal.
Tom Brito
3
@ TomBrito, lastIndexOfmemindai seluruh string hanya jika tidak menemukan kecocokan, atau menemukan kecocokan di awal. Jika ada kecocokan di akhir maka itu berfungsi proporsional dengan panjang akhiran. Ya, /asdf$/.test(str)hasil benar ketika strdiakhiri dengan "asdf".
Mike Samuel
3
@ Tom Brito, Ini literal ekspresi reguler. Sintaksnya dipinjam dari Perl. Lihat developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… atau untuk tingkat detail yang tidak perlu, lihat bagian 7.8.5 dari spesifikasi bahasa EcmaScript.
Mike Samuel
2
+1 untuk kompatibilitas lintas-browser. Diuji pada Chrome 28.0.1500.72 m, Firefox 22.0, dan IE9.
Adrien Be
91
  1. Sayangnya tidak.
  2. if( "mystring#".substr(-1) === "#" ) {}
Phillip B Oldham
sumber
14
@Anthony, um ... jadi gunakan .Length-1, apa masalahnya? if (mystring.substr (mystring.length-1) === "#") {} berfungsi dengan baik di IE.
BrainSlugs83
12
@ BrainSlugs83 - itulah masalahnya: sintaks '.length-1' bekerja di IE, dan sintaks '-1' tidak. Ini sesuatu yang perlu diingat, jadi beri +1 pada Anthony untuk tipnya.
avramov
2
Tidak bisa Anda gunakan slice()? Ini bekerja untuk saya dalam tes IE7 cepat saya.
alex
IE yang aneh. kapan itu akan mati?
ahnbizcad
67

Ayo, ini adalah endsWithimplementasi yang benar :

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

menggunakan lastIndexOfhanya menciptakan loop CPU yang tidak perlu jika tidak ada kecocokan.

Oskar Liljeblad
sumber
2
Sepakat. Saya benar-benar merasa seperti ini adalah solusi paling berkinerja yang ditawarkan karena memiliki aborsi awal / pemeriksaan kewarasan, pendek dan ringkas, elegan (overloading the prototipe string) dan substring sepertinya jauh lebih sedikit dari hit sumber daya daripada memutar mesin regex.
BrainSlugs83
Juga suka solusi ini. Hanya nama fungsinya yang salah eja. Harus "berakhir dengan".
xmedeko
3
@ BrainSlugs83 Sudah beberapa tahun, tapi sekarang metode ini tidak lebih cepat dari metode 'indexOf' yang disebutkan di atas oleh chakrit, dan di bawah Safari, 30% lebih lambat! Berikut ini adalah tes jsPerf untuk kasus kegagalan lebih dari sekitar string 50-karakter: jsperf.com/endswithcomparison
Brent Faust
4
Mungkin harus digunakan ===.
Timmmm
56

Versi ini menghindari membuat substring, dan tidak menggunakan ekspresi reguler (beberapa jawaban regex di sini akan berfungsi; yang lain rusak):

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

Jika kinerja penting bagi Anda, sebaiknya uji apakah lastIndexOfsebenarnya lebih cepat daripada membuat substring atau tidak. (Ini mungkin tergantung pada mesin JS yang Anda gunakan ...) Mungkin lebih cepat dalam kasus yang cocok, dan ketika string kecil - tetapi ketika string besar itu perlu melihat kembali melalui semuanya bahkan meskipun kami tidak terlalu peduli :(

Untuk memeriksa satu karakter, menemukan panjang dan menggunakan charAtmungkin merupakan cara terbaik.

Jon Skeet
sumber
2
Jika this.lastIndexOf () mengembalikan -1, Anda bisa menekan case di mana ia mengembalikan dependong true pada this.length dan str.length. Tambahkan tes yang lastIndexOf ()! = -1.
ebruchez
1
Mengapa metode regex rusak?
izb
2
@izb: Jawaban yang lebih lama dari milik saya yang mencoba digunakan str+"$"sebagai regex rusak, karena mereka mungkin bukan regex yang valid.
Jon Skeet
26

Tidak melihat apporach dengan slicemetode. Jadi saya tinggalkan saja di sini:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}
Nikita Koksharov
sumber
1
Anda dapat menyederhanakannya sedikit lebih: return str.slice (-1) === akhiran;
Erik K.
2
Ini jawaban terbaik. Tidak yakin mengapa itu tidak memiliki lebih banyak upvotes.
nucleartide
17
return this.lastIndexOf(str) + str.length == this.length;

tidak berfungsi dalam kasus di mana panjang string asli kurang dari panjang string pencarian dan string pencarian tidak ditemukan:

lastIndexOf mengembalikan -1, lalu Anda menambahkan panjang string pencarian dan Anda dibiarkan dengan panjang string asli.

Perbaikan yang mungkin adalah

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length
pengguna73745
sumber
30
Anda telah mendapatkan lencana "Ditemukan kesalahan dalam jawaban Jon Skeet". Lihat profil Anda untuk detailnya.
bobince
17

Dari developer.mozilla.org String.prototype.endsWith ()

Ringkasan

The endsWith()Metode menentukan apakah string berakhir dengan karakter dari string lain, kembali benar atau salah yang sesuai.

Sintaksis

str.endsWith(searchString [, position]);

Parameter

  • searchString : Karakter yang akan dicari di akhir string ini.

  • posisi : Cari di dalam string ini seolah-olah string ini hanya selama ini; default untuk panjang aktual string ini, dijepit dalam rentang yang ditentukan oleh panjang string ini.

Deskripsi

Metode ini memungkinkan Anda menentukan apakah suatu string berakhir atau tidak.

Contohnya

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

Spesifikasi

Spesifikasi Bahasa ECMAScript Edisi 6 (ECMA-262)

Kompatibilitas browser

Kompatibilitas browser

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

-- Atau --

if( ("mystring#").match(/#$/) )
duckyflip
sumber
8
String.prototype.endsWith = function(str) 
{return (this.match(str+"$")==str)}

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

saya harap ini membantu

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…

cara tradisional

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

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}
Mohammed Rafeeq
sumber
Anda harus melarikan diri dari string Anda untuk urutan escape regex
Juan Mendes
1
Ekspresi reguler lambat bahkan dalam bahasa cepat. Periksa ujung string.
Daniel Nuriyev
8

Saya tidak tahu tentang Anda, tetapi:

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

Mengapa menggunakan ekspresi reguler? Mengapa mengacaukan prototipe? substr? Ayo...

Tici
sumber
kadang-kadang lebih baik kalau
basah
8

Hanya alternatif cepat lain yang bekerja seperti pesona bagi saya, menggunakan regex:

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

Jika Anda menggunakan lodash :

_.endsWith('abc', 'c'); // true

Jika tidak menggunakan lodash, Anda dapat meminjam dari sumbernya .

Dheeraj Vepakomma
sumber
6

Saya baru saja belajar tentang perpustakaan string ini:

http://stringjs.com/

Sertakan file js dan kemudian gunakan Svariabel seperti ini:

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

Itu juga dapat digunakan di NodeJS dengan menginstalnya:

npm install string

Kemudian membutuhkannya sebagai Svariabel:

var S = require('string');

Halaman web juga memiliki tautan ke pustaka string alternatif, jika ini tidak sesuai keinginan Anda.

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

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

  return false;
}
Tabish Usman
sumber
1
Lebih baik jika Anda menjelaskan mengapa kode Anda memecahkan masalah. Lihat panduan Cara Menjawab .
brasofilo
argumen suffix harus dipindai untuk ekspresi regex yang harus diloloskan. menggunakan indexOf atau lastIndexOf tampaknya menjadi pilihan yang lebih baik.
vlad_tepesch
Ini tidak akan berfungsi jika sufiks berisi salah satu karakter berikut:. * +? ^ =!: $ {} () [] / \
gtournie
4

Begitu banyak hal untuk masalah sekecil ini, cukup gunakan Ekspresi Reguler ini

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

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

LahiruBandara
sumber
4

Sudah bertahun-tahun untuk pertanyaan ini. Biarkan saya menambahkan pembaruan penting untuk pengguna yang ingin menggunakan jawaban chakrit yang paling banyak dipilih.

Fungsi 'endsWith' sudah ditambahkan ke JavaScript sebagai bagian dari ECMAScript 6 (teknologi eksperimental)

Rujuk di sini: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Oleh karena itu sangat disarankan untuk menambahkan cek untuk keberadaan implementasi asli seperti yang disebutkan dalam jawaban.

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

Cara untuk bukti di masa depan dan / atau mencegah penimpaan prototipe yang ada akan menjadi tes untuk melihat apakah sudah ditambahkan ke prototipe String. Inilah pendapat saya tentang versi berperingkat tinggi non-regex.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}
Dan Doyon
sumber
Menggunakan if (!String.prototype.hasOwnProperty("endsWith"))adalah cara terbaik. Dengan typeof, "Mootools dan beberapa perpustakaan AJAX lainnya akan mengacaukan Anda", menurut "Crockford on JavaScript - Level 7: ECMAScript 5: The New Parts", pada 15:50 menit.
XP1
2

Jawaban chakrit yang diterima adalah cara yang solid untuk melakukannya sendiri. Namun, jika Anda sedang mencari solusi paket, saya sarankan melihat underscore.string , seperti yang ditunjukkan @mlunoe. Menggunakan underscore.string, kodenya adalah:

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

jika Anda tidak ingin menggunakan lasIndexOf atau substr maka mengapa tidak melihat string dalam keadaan alami (mis. sebuah array)

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

atau sebagai fungsi mandiri

function strEndsWith(str,suffix) {
    if (str[str.length - 1] == suffix) return true;
    return false;
}
pengguna511941
sumber
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)/));
Ebubekir Dirican
sumber
1

Setelah semua penghitungan yang panjang itu, saya menemukan potongan kode ini sederhana dan mudah dimengerti!

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

Ini adalah implementasi dari tujuan dengan: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

Singh123
sumber
1

Ini adalah implementasi dari endsWith:

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

Ini didasarkan pada jawaban yang diterima @ charkit yang memungkinkan Array string, atau string untuk diteruskan sebagai argumen.

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

Ini memerlukan underscorejs - tetapi mungkin dapat disesuaikan untuk menghapus ketergantungan garis bawah.

Matthew Brown
sumber
1
Ini adalah solusi yang buruk, daripada jika Anda sudah menggunakan garis bawah Anda harus menambahkan epeli.github.io/underscore.string ini ke dependensi Anda dan menggunakan implementasinya:_.str.endsWith
mlunoe
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
        ;
    };
}

Manfaat:

  • Versi ini tidak hanya menggunakan kembali indexOf.
  • Performa terbaik di string panjang. Berikut ini adalah tes kecepatan http://jsperf.com/starts-ends-with/4
  • Sepenuhnya kompatibel dengan spesifikasi ecmascript. Itu melewati tes
termi
sumber
0

Jangan gunakan ekspresi reguler. Mereka lambat bahkan dalam bahasa cepat. Tulis saja fungsi yang memeriksa ujung string. Perpustakaan ini memiliki contoh yang bagus: groundjs / util.js . Hati-hati menambahkan fungsi ke String.prototype. Kode ini memiliki contoh yang bagus tentang bagaimana melakukannya: groundjs / prototype.js Secara umum, ini adalah pustaka tingkat bahasa yang bagus: groundjs Anda juga dapat melihat pada lodash

Daniel Nuriyev
sumber
0

semuanya adalah contoh yang sangat berguna. Menambahkan String.prototype.endsWith = function(str)akan membantu kita cukup memanggil metode untuk memeriksa apakah string kita berakhir atau tidak, juga regexp juga akan melakukannya.

Saya menemukan solusi yang lebih baik daripada solusi saya. Terimakasih semuanya.

Bobby Kumar
sumber
0

Untuk naskah kopi

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
Quanlong
sumber