JavaScript ile


1103

Bir dizenin JavaScript'te belirli bir karakterle bitip bitmediğini nasıl kontrol edebilirim?

Örnek: Bir dizem var

var str = "mystring#";

Bu dize ile bitip bitmediğini bilmek istiyorum #. Nasıl kontrol edebilirim?

  1. endsWith()JavaScript'te bir yöntem var mı ?

  2. Sahip olduğum bir çözüm, dizenin uzunluğunu alıp son karakteri alıp kontrol etmektir.

Bu en iyi yol mu yoksa başka bir yol var mı?



Yanıtlar:


1764

GÜNCELLEME (24 Kasım 2015):

Bu yanıt ilk olarak 2010 yılında (SIX yıl önce) yayınlanmıştır, bu yüzden lütfen bu anlayışlı yorumları not edin:


ORİJİNAL CEVAP:

Bunun bir yıllık bir soru olduğunu biliyorum ... ama buna da ihtiyacım var ve çapraz tarayıcı çalışması için buna ihtiyacım var ... herkesin cevaplarını ve yorumlarını birleştirerek biraz basitleştirelim:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Alt dize oluşturmaz
  • indexOfEn hızlı sonuçlar için yerel işlevi kullanır
  • İleri indexOfatlamak için ikinci parametresini kullanarak gereksiz karşılaştırmaları atlayın
  • Internet Explorer'da çalışır
  • NO Regex komplikasyonları

Ayrıca, yerel veri yapısının prototiplerinde bir şeyler doldurmaktan hoşlanmıyorsanız, işte bağımsız bir sürüm:

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

EDIT: @hamish tarafından belirtildiği gibi, güvenli tarafta hata yapmak ve bir uygulamanın zaten sağlanmış olup olmadığını kontrol etmek istiyorsanız, şöyle bir typeofkontrol ekleyebilirsiniz :

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

42
Google Çalışanları Güncellemesi - Görünüşe göre ECMA6 bu işlevi ekliyor. MDN makalesinde ayrıca bir çoklu dolgu gösterilmektedir. developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
Shauna

2
@ lukas.pukenis sonuna atlar ve sonun sadece bir sonunu kontrol eder. arama dizesinin başka bir yerde görünmesi önemli değildir.
chakrit

3
"Sonek" bağımsız değişkeni tanımlanmadığında "durum için bir denetim ekleme: if (typeof String.prototype.endsWith! == 'function') {String.prototype.endsWith = function (sonek) {return this.indexOf (sonek , this.length - ((sonek && sonek.length) || 0))! == -1;};}
Mandeep

2
Bahsettiğiniz regex komplikasyonları nelerdir?
IcedDante

5
Modern tarayıcılarda alt dizeler oluşturmak pahalı değildir; bu cevabın yayınlandığı 2010'da olmuş olabilir. Bu günlerde, basit this.substr(-suffix.length) === suffixyaklaşım IE11'de olduğu gibi Chrome'da en hızlı indexOfve Firefox'ta sadece% 4 daha yavaş (fergetaboutit bölgesi): jsperf.com/endswith-stackoverflow/14 Ve sonuç yanlış olduğunda tahtada daha hızlı: jsperf .com / uçları-stackoverflow-when-false Tabii ki, ES6 ekleme endsWithile nokta tartışmalıdır. :-)
TJ Crowder

295
/#$/.test(str)

tüm tarayıcılarda çalışır, maymun düzeltme eki gerektirmez Stringve lastIndexOfeşleşme olmadığında tüm dizeyi taramayı gerektirmez .

Normal ifade gibi özel karakterler içerebilecek sabit bir dizeyi eşleştirmek istiyorsanız '$', aşağıdakileri kullanabilirsiniz:

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

ve sonra böyle kullanabilirsiniz

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

10
Sabit bir alt dizeyi kontrol ediyorsanız bu güzel ve basittir.
Warren Blanchet

1
lastIndexOf tüm dizeyi tarar mı? Başından sonuna kadar arayacağını düşündüm.
Tom Brito

3
@ TomBrito, lastIndexOftüm dizeyi yalnızca eşleşme bulamazsa veya başlangıçta bir eşleşme bulursa tarar. Sonunda bir eşleşme varsa, son ekin uzunluğu ile orantılı olarak çalışır. Evet, /asdf$/.test(str)ne zaman gerçek verir struçları ile "asdf".
Mike Samuel

3
@Tom Brito, Bu düzenli bir ifade değişmezidir. Sözdizimi Perl'den ödünç alınmıştır. Bkz developer.mozilla.org/en/Core_JavaScript_1.5_Guide/... veya ayrıntı gereksiz bir seviye için, ECMAScript dil şartnamenin bölümüne 7.8.5 bakın.
Mike Samuel

2
Tarayıcılar arası uyumluluk için +1. Chrome 28.0.1500.72 m, Firefox 22.0 ve IE9 üzerinde test edildi.
Adrien Be

91
  1. Ne yazık ki değil.
  2. if( "mystring#".substr(-1) === "#" ) {}

14
@ Anthony, um ... yani .Length-1 kullan, sorun nedir? if (mystring.substr (mystring.length-1) === "#") {} IE'de gayet iyi çalışıyor.
BrainSlugs83

12
@ BrainSlugs83 - sorun tam olarak bu: '.length-1' sözdizimi IE'de çalışıyor ve '-1' sözdizimi çalışmıyor. Akılda tutulması gereken bir şey, bu yüzden bahşiş için Anthony'ye +1.
avramov

2
Kullanamaz mısın slice()? Hızlı IE7 testimde benim için çalışıyor.
alex

freaken IE. ne zaman ölecek
ahnbizcad

67

Hadi, bu doğru endsWithuygulama:

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

kullanarak lastIndexOfeşleşme yoksa yalnızca gereksiz CPU döngüleri oluşturur.


2
Kabul. Gerçekten, erken iptal / akıl sağlığı kontrolüne sahip olduğu için sunulan en performanslı çözüm olduğunu hissediyorum, kısa ve özlü, zarif (dize prototipini aşırı yükleme) ve alt dize, regex motorunu döndürmekten çok daha az bir kaynak vuruşu gibi görünüyor.
BrainSlugs83

Ayrıca bu çözüm gibi. Yalnızca işlev adı yanlış yazılmıştır. "EndWith" olmalıdır.
xmedeko

3
@ BrainSlugs83 Birkaç yıl oldu, ama şimdi bu yöntem yukarıda chakrit tarafından belirtilen 'indexOf' yönteminden daha hızlı değil ve Safari altında% 30 daha yavaş! İşte 50 karakterlik bir dize üzerinde başarısızlık durumu için bir jsPerf testi: jsperf.com/endswithcomparison
Brent Faust

4
Muhtemelen ===olsa kullanmalısınız .
Timmmm

56

Bu sürüm bir alt dize oluşturmaktan kaçınır ve düzenli ifadeler kullanmaz (burada bazı normal ifadeler yanıt verir; diğerleri bozulur):

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

Performans sizin için önemliyse, test edip etmeyeceğiniz lastIndexOf bir alt dize oluşturmaktan daha hızlı . (Kullandığınız JS motoruna bağlı olabilir ...) Eşleştirme durumunda daha hızlı olabilir ve dize küçük olduğunda - ancak dize büyük olduğunda bile her şeye geri bakması gerekir gerçi umursamıyoruz :(

Tek bir karakteri kontrol etmek için, uzunluğu bulmak ve sonra kullanmak charAtmuhtemelen en iyi yoldur.


2
This.lastIndexOf () -1 döndürürse, this.length ve str.length öğelerine bağlı olarak true döndürdüğü durumlara basabilirsiniz. LastIndexOf ()! = -1 olan bir test ekleyin.
ebruchez

1
Normal ifade yöntemi neden bozuk?
izb

2
@izb: Normal str+"$"regex olarak kullanmaya çalışan benimkinden daha eski cevaplar bozuldu, çünkü geçerli regexler olmayabilir.
Jon Skeet

26

sliceYöntemi ile apporach görmedim . Ben sadece burada bırakıyorum:

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

1
Biraz daha basitleştirebilirsiniz: return str.slice (-1) === sonek;
Erik K.

2
Bu en iyi cevap. Neden daha fazla oy vermediğinden emin değilim.
nucleartide

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

orijinal dize uzunluğunun arama dizesi uzunluğundan daha az olduğu ve arama dizesinin bulunmadığı durumlarda çalışmaz:

lastIndexOf -1 değerini döndürür, arama dizesi uzunluğunu eklersiniz ve orijinal dizenin uzunluğunda kalırsınız.

Olası bir düzeltme

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

30
“Jon Skeet cevabında bir hata buldum” rozetini kazandınız. Ayrıntılar için profilinize bakın.
bobince

17

Developer.mozilla.org sitesinden String.prototype.endsWith ()

özet

endsWith()Yöntem, müşteri kimlik doğru veya uygun olarak yanlış geri başka bir dize, özeliklerine sahip olan bir dizi biter.

Sözdizimi

str.endsWith(searchString [, position]);

Parametreler

  • searchString : Bu dizenin sonunda aranacak karakterler.

  • position : Bu dize içinde, bu dize yalnızca bu kadar uzun gibi arama yapın; varsayılan olarak, bu dizenin uzunluğu tarafından belirlenen aralığa kenetlenmiş bu dizenin gerçek uzunluğuna ayarlanır.

Açıklama

Bu yöntem, bir dizenin başka bir dizeyle bitip bitmeyeceğini belirlemenizi sağlar.

Örnekler

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

Özellikler

ECMAScript Dil Özellikleri 6. Baskı (ECMA-262)

Tarayıcı Uyumluluğu

Tarayıcı Uyumluluğu


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

- Veya -

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

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

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

Umarım bu yardımcı olur

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…

geleneksel yol

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

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

Normal ifade kaçış dizileri için dizeden kaçmak zorunda
Juan Mendes

1
Hızlı ifadelerde bile düzenli ifadeler yavaştır. Bir dizenin sonunu kontrol edin.
Daniel Nuriyev

8

Seni bilmiyorum ama:

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

Neden düzenli ifadeler? Neden prototiple uğraşıyorsun? substr? Hadi...


çünkü bazen ISLAK olduğunda daha iyidir
Martin Capodici

8

Regex kullanarak benim için bir cazibe gibi çalışan hızlı bir alternatif:

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


6

Ben sadece bu dize kütüphanesi hakkında öğrendim:

http://stringjs.com/

Js dosyasını ekleyin ve sonra aşağıdaki Sgibi değişkeni kullanın :

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

NodeJS'de kurarak da kullanılabilir:

npm install string

Sonra Sdeğişken olarak gerektirir :

var S = require('string');

Web sayfanız, süslemenizi almazsa, alternatif dize kitaplıklarına bağlantılar da içerir.


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

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

  return false;
}

1
Kodunuzun sorunu neden çözdüğünü açıklarsanız daha iyi olur . Nasıl Cevap Verilir kılavuzuna bakın .
brasofilo

sonek bağımsız değişkeni, kaçması gereken normal ifade ifadeleri için taranmalıdır. indexOf veya lastIndexOf kullanmak daha iyi bir seçenek gibi görünüyor.
vlad_tepesch

Sonek şu karakterlerden herhangi birini içeriyorsa çalışmaz
:.

4

Böylesine küçük bir problem için pek çok şey, sadece bu Normal İfadeyi kullanın

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

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


4

Bu soru için yıllar geçti. En çok oy alan chakrit'in cevabını kullanmak isteyen kullanıcılar için önemli bir güncelleme ekleyeyim.

ECMAScript 6'nın (deneysel teknoloji) bir parçası olarak JavaScript'e zaten 'uçlar' işlevleri eklenmiş

Buradan bakın: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Bu nedenle, yanıtta belirtildiği gibi, yerel uygulamanın varlığının kontrolünün eklenmesi önemle tavsiye edilir.


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

2

Gelecekteki kanıtların ve / veya mevcut prototipin üzerine yazılmasını önlemenin bir yolu, String prototipine zaten eklenmiş olup olmadığını görmek için test kontrolü olacaktır. İşte regex olmayan derece derecelendirilmiş sürümü benim almak.

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

Kullanmak if (!String.prototype.hasOwnProperty("endsWith"))en iyi yoldur. İle typeof, "JavaScript Crockford - Seviye 7 Yeni Parçalar: ECMAScript'e 5" e göre, "mooTools ve diğer AJAX kütüphaneleri bazı sizi berbat edecek" 15:50 min.
XP1

2

@ chakrit'in kabul edilen cevabı kendiniz yapmanın sağlam bir yoludur. Ancak, bir paketlenmiş çözüm arıyorsanız, ben bir göz atmanızı öneririz underscore.string @mlunoe belirttiği gibi,. Underscore.string kullanıldığında kod şöyle olur:

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

1

lasIndexOf veya substr kullanmak istemiyorsanız, neden dizeye doğal haliyle (yani bir dizi) bakmıyorsunuz?

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

veya bağımsız bir işlev olarak

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

Tüm bu uzun cevapların ardından, bu kod parçasını basit ve anlaşılması kolay buldum!

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

1

Bu, uçların uygulanmasıdır: String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }


1

Bu, aşağıdakilerin uygulanmasıdır endsWith:

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

0

Bu, @ charkit'in kabul edilen cevabı üzerine ya bir dizi dizisinin ya da dizenin argüman olarak aktarılmasına izin verir.

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

Bu alt çizgi gerektirir - ancak alt çizgi bağımlılığını kaldıracak şekilde ayarlanabilir.


1
Bu kötü bir çözümdür, daha ziyade zaten alt çizgi kullanıyorsanız, bu epeli.github.io/underscore.string'i bağımlılıklarınıza eklemeniz ve uygulamalarını kullanmanız gerekir:_.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
        ;
    };
}

Yararları:


0

Normal ifadeler kullanmayın. Hızlı dillerde bile yavaştırlar. Bir dizenin sonunu kontrol eden bir işlev yazmanız yeterlidir. Bu kütüphane güzel örnekler vardır: groundjs / util.js . String.prototype öğesine bir işlev eklerken dikkatli olun. Bu kodun nasıl yapılacağına dair güzel örnekleri vardır: groundjs / prototype.js Genel olarak, bu güzel bir dil düzeyinde kütüphane: groundjs Ayrıca lodash'a da bakabilirsiniz.


0

hepsi çok faydalı örneklerdir. EklemeString.prototype.endsWith = function(str) , dizemizin onunla bitip bitmediğini kontrol etmek için yöntemi çağırmamıza yardımcı olacaktır, iyi regexp de bunu yapacaktır.

Benimkinden daha iyi bir çözüm buldum. Herkese teşekkürler.


0

Kahve için

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.