Bir dizeden belirli bir karakteri kırp


120

Bu yönteme eşdeğer JavaScript nedir C#:

var x = "|f|oo||"; 
var y = x.Trim('|'); //  "f|oo"

C #, seçilen karakteri dizenin yalnızca başında ve sonunda kırpar !

Yanıtlar:


155

Bir satır yeterlidir:

var x = '|f|oo||';
var y = x.replace(/^\|+|\|+$/g, '');
document.write(x + '<br />' + y);

^\|+   beginning of the string, pipe, one or more times
|      or
\|+$   pipe, one or more times, end of the string

Genel bir çözüm:

function trim (s, c) {
  if (c === "]") c = "\\]";
  if (c === "\\") c = "\\\\";
  return s.replace(new RegExp(
    "^[" + c + "]+|[" + c + "]+$", "g"
  ), "");
}

chars = ".|]\\";
for (c of chars) {
  s = c + "foo" + c + c + "oo" + c + c + c;
  console.log(s, "->", trim(s, c));
}


35

İyi anladıysam, belirli bir karakteri yalnızca dizenin başında veya sonundaysa kaldırmak istersiniz (örn: ||fo||oo||||olmalıdır foo||oo). Aşağıdaki gibi geçici bir işlev oluşturabilirsiniz:

function trimChar(string, charToRemove) {
    while(string.charAt(0)==charToRemove) {
        string = string.substring(1);
    }

    while(string.charAt(string.length-1)==charToRemove) {
        string = string.substring(0,string.length-1);
    }

    return string;
}

Bu işlevi aşağıdaki kodla test ettim:

var str = "|f|oo||";
$( "#original" ).html( "Original String: '" + str + "'" );
$( "#trimmed" ).html( "Trimmed: '" + trimChar(str, "|") + "'" );

3
Bu, çöp toplayıcı için eğlenceli bir test olabilir, ancak müşterilerinizi buna tabi tutmanızı tavsiye etmem.
Sorensen

18

Aşağıdaki gibi normal bir ifade kullanabilirsiniz:

var x = "|f|oo||";
var y = x.replace(/^[\|]+|[\|]+$/g, "");
alert(y); // f|oo

GÜNCELLEME:

Bunu bir fonksiyona genellemek isterseniz, aşağıdakileri yapabilirsiniz:

var escapeRegExp = function(strToEscape) {
    // Escape special characters for use in a regular expression
    return strToEscape.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

var trimChar = function(origString, charToTrim) {
    charToTrim = escapeRegExp(charToTrim);
    var regEx = new RegExp("^[" + charToTrim + "]+|[" + charToTrim + "]+$", "g");
    return origString.replace(regEx, "");
};

var x = "|f|oo||";
var y = trimChar(x, "|");
alert(y); // f|oo

17

bu soruyu güncel tutmak için:

ES6 yayma operatörünü kullanarak regex işlevi yerine seçeceğim bir yaklaşım.

function trimByChar(string, character) {
  const first = [...string].findIndex(char => char !== character);
  const last = [...string].reverse().findIndex(char => char !== character);
  return string.substring(first, string.length - last);
}

@Fabian'ın yorumundan sonra geliştirilmiş sürüm (yalnızca aynı karakteri içeren dizeleri işleyebilir)

function trimByChar(string, character) {
  const arr = Array.from(string);
  const first = arr.indexOf(character);
  const last = arr.reverse().indexOf(character);
  return string.substring(first + 1, string.length - last - 1);
}

2
Normal ifadelerin burada gereğinden fazla olduğunu biliyorum, ancak bu özel uygulamayı neden seçmelisiniz?
Nicholas Shanks

2
bu uygulama, çünkü ben şahsen onu iyi okunabilir buluyorum. Normal ifade yok çünkü normal ifade motorlarındaki karar "ağaç" çok daha büyük. ve özellikle, kırpmak için kullanılan normal ifadeler, normal ifade motoru içinde geriye doğru izlemeye yol açan sorgu karakterleri içerdiğinden. bu tür motorlar genellikle modeli, makine talimatlarını andıran bayt kodunda derler. motor daha sonra kodu çalıştırarak komuttan talimata atlar. bir talimat başarısız olduğunda, girişi eşleştirmek için başka bir yol bulmak için geri döner. ergo nec'den çok daha fazla oluyor.
Robin F.

Yanıtınız için teşekkürler, ancak bunu yapmanın diğer normal ifade olmayan yolları yerine neden bunu seçtiğinizi açıklamanızı istememe rağmen - sanırım sadece "okunabilir bulduğumdan" daha fazlasını umuyordum.
Nicholas Shanks

1
@RobinF. findIndex () ve reverse () 'in döngü içermediğini mi düşünüyorsunuz? Tekrar düşün.
Andrew

1
İki ek açıklama: Yalnızca kırpılacak karakteri içeren bir dize hiç kırpılmayacaktır. Diğer nokta şudur: Yayılma operatörü ile dizeyi bir dizi halinde patlatmak babel'i karıştırır ve onu [].concat(string)istenen sonuç olmayan bir sonuca dönüştürür. Kullanmak Array.from(string)işe yarayacak.
Fabian

14

Gözü yormayan normal ifade içermeyen bir sürüm:

const trim = (str, chars) => str.split(chars).filter(Boolean).join(chars);

Kenarlarda karakterlerin tekrarı olmadığından emin olduğumuz kullanım durumları için.


oldukça ilginç ... bu yüzden bölünmüş, bölünen her bir sınırlayıcıya eşit olan tanımsız öğeyi döndürürconst trim = (str, chars) => str.split(chars).filter(x => { Boolean(x); console.log(typeof(x), x, Boolean(x)); }).join(chars); const str = "#//#//abc#//test#//end#//"; console.log(trim(str, '#//'));
TamusJRoyce

10

Daha uzun dizelerle uğraşıyorsanız, tahsis edilen dizelerin sayısını sıfıra veya bire düşürerek bunun diğer seçeneklerin çoğundan daha iyi performans göstermesi gerektiğine inanıyorum:

function trim(str, ch) {
    var start = 0, 
        end = str.length;

    while(start < end && str[start] === ch)
        ++start;

    while(end > start && str[end - 1] === ch)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trim('|hello|world|', '|'); // => 'hello|world'

Veya birden çok karakter kümesinden kırpmak istiyorsanız:

function trimAny(str, chars) {
    var start = 0, 
        end = str.length;

    while(start < end && chars.indexOf(str[start]) >= 0)
        ++start;

    while(end > start && chars.indexOf(str[end - 1]) >= 0)
        --end;

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimAny('|hello|world   ', [ '|', ' ' ]); // => 'hello|world'
// because '.indexOf' is used, you could also pass a string for the 2nd parameter:
trimAny('|hello| world  ', '| '); // => 'hello|world'

DÜZENLEME: Eğlence için kelimeleri kırpın (tek tek karakterler yerine)

// Helper function to detect if a string contains another string
//     at a specific position. 
// Equivalent to using `str.indexOf(substr, pos) === pos` but *should* be more efficient on longer strings as it can exit early (needs benchmarks to back this up).
function hasSubstringAt(str, substr, pos) {
    var idx = 0, len = substr.length;

    for (var max = str.length; idx < len; ++idx) {
        if ((pos + idx) >= max || str[pos + idx] != substr[idx])
            break;
    }

    return idx === len;
}

function trimWord(str, word) {
    var start = 0,
        end = str.length,
        len = word.length;

    while (start < end && hasSubstringAt(str, word, start))
        start += word.length;

    while (end > start && hasSubstringAt(str, word, end - len))
        end -= word.length

    return (start > 0 || end < str.length) ? str.substring(start, end) : str;
}

// Usage:
trimWord('blahrealmessageblah', 'blah');

1
Bu çözümü tercih ediyorum çünkü aslında kısa değil, gerçekten verimli.
tekHedd

Tercih edilmesi gerektiğine katılıyorum. Verdiğim cevabın yerini alır.
TamusJRoyce

9

Bu, bir seferde birkaç karakteri kesebilir:

String.prototype.trimChars = function (c) {
  var re = new RegExp("^[" + c + "]+|[" + c + "]+$", "g");
  return this.replace(re,"");
}

var x = "|f|oo||"; 
x =  x.trimChars('|'); // f|oo

var y = "..++|f|oo||++..";
y = y.trimChars('|.+'); // f|oo

var z = "\\f|oo\\"; // \f|oo\

// For backslash, remember to double-escape:
z = z.trimChars("\\\\"); // f|oo

@fubo: Hayır, pek değil. Bu bir demo, bir konsola yapıştırırsanız, sadece sonucu yazdıracaktır. Ama kafa karıştırıcı olabileceğini anlıyorum, bu yüzden onu düzenledim.
marlar

2

Bu işlevleri programınızda tanımlarsanız, dizeleriniz, trimverilen tüm karakterleri kesebilen yükseltilmiş bir sürümüne sahip olacaktır :

String.prototype.trimLeft = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("^[" + charlist + "]+"), "");
};

String.prototype.trim = function(charlist) {
	return this.trimLeft(charlist).trimRight(charlist);
};

String.prototype.trimRight = function(charlist) {
	if (charlist === undefined)
	charlist = "\s";

	return this.replace(new RegExp("[" + charlist + "]+$"), "");
};

var withChars = "/-center-/"
var withoutChars = withChars.trim("/-")
document.write(withoutChars)

Kaynak

https://www.sitepoint.com/trimming-strings-in-javascript/


1

Bildiğim kadarıyla jQuery, sorduğunuz yöntemde yerleşik bir işleve sahip değildir. Bununla birlikte, javascript ile dizenizin içeriğini değiştirmek için yalnızca değiştir'i kullanabilirsiniz:

x.replace(/|/i, ""));

Bu, tüm | hiçbir şey ile.


kaldırmanın bir yolu var mı | sadece başında / sonunda mı?
fubo

Aslında bu gönderinin sorunuzu en hızlı şekilde
çözeceğini düşünüyorum

@fubo Tabii ... $Sadece sonunda böyle bir şey atın : "||spam|||".replace(/\|+$/g, "")veya ^sadece başlangıçta böyle bir şey:"||spam|||".replace(/^\|+/g, "")
ruffin

1

Bu, tüm öndeki ve sondaki ayırıcıları kırpar

const trim = (str, delimiter) => {
  const pattern = `[^\\${delimiter}]`;
  const start = str.search(pattern);
  const stop = str.length - str.split('').reverse().join('').search(pattern);
  return str.substring(start, stop);
}

const test = '||2|aaaa12bb3ccc|||||';
console.log(trim(test, '|')); // 2|aaaa12bb3ccc

1

Lodash'a ve trimişlevi nasıl uyguladıklarına bakmanızı öneririm .

Belgeler ve kaynak için Lodash Trim'e bakın işlemini yapan tam kodu görmek için .

Bunun sorunuza kesin bir cevap vermediğini biliyorum, ancak bence böyle bir soru için bir kütüphaneye referans vermenin iyi olacağını düşünüyorum çünkü diğerleri onu yararlı bulabilir.


1
@TamusJRoyce not the same
gdbdable

@devi Sadece katılıyorum. Yorum için teşekkürler. topluluk destekli bir araca bakarak iyi cevap.
TamusJRoyce

1

Bu görevi çözmenin en iyi yolu (PHP trimişlevine benzer ):

function trim( str, charlist ) {
  if ( typeof charlist == 'undefined' ) {
    charlist = '\\s';
  }
  
  var pattern = '^[' + charlist + ']*(.*?)[' + charlist + ']*$';
  
  return str.replace( new RegExp( pattern ) , '$1' )
}

document.getElementById( 'run' ).onclick = function() {
  document.getElementById( 'result' ).value = 
  trim( document.getElementById( 'input' ).value,
  document.getElementById( 'charlist' ).value);
}
<div>
  <label for="input">Text to trim:</label><br>
  <input id="input" type="text" placeholder="Text to trim" value="dfstextfsd"><br>
  <label for="charlist">Charlist:</label><br>
  <input id="charlist" type="text" placeholder="Charlist" value="dfs"><br>
  <label for="result">Result:</label><br>
  <input id="result" type="text" placeholder="Result" disabled><br>
  <button type="button" id="run">Trim it!</button>
</div>

Not: Çoğu insan bunu daha önce yaptığında neden cevabımı gönderdim? Tüm yanıtlarda "en iyi" hatayı bulduğum için: hepsi "*" yerine "+" meta kullandı, çünkü " trimBAŞLANGIÇ VE / VEYA SONUNDA İSE karakterleri kaldırmalı, ancak başka durumda orijinal dizeyi döndürmeli .


0

@leaf'ın cevabını genişleterek, işte birden çok karakter alabilen bir cevap:

var trim = function (s, t) {
  var tr, sr
  tr = t.split('').map(e => `\\\\${e}`).join('')
  sr = s.replace(new RegExp(`^[${tr}]+|[${tr}]+$`, 'g'), '')
  return sr
}

0

@ Pho3niX83'ün çözümünü beğendim ...

"Char" yerine "kelime" ile uzatalım ...

function trimWord(_string, _word) {

    var splitted = _string.split(_word);

    while (splitted.length && splitted[0] === "") {
        splitted.shift();
    }
    while (splitted.length && splitted[splitted.length - 1] === "") {
        splitted.pop();
    }
    return splitted.join(_word);
};

0
function trim(text, val) {
    return text.replace(new RegExp('^'+val+'+|'+val+'+$','g'), '');
}



-1
String.prototype.TrimStart = function (n) {
    if (this.charAt(0) == n)
        return this.substr(1);
};

String.prototype.TrimEnd = function (n) {
    if (this.slice(-1) == n)
        return this.slice(0, -1);
};

Yalnızca bir tekrarı kaldırır, ancak karakter tamamen kesilene kadar kırpılmaz
KoalaBear

1
Varsayılan dize prototipini geçersiz kılmayın ya da daha sonra sorun istiyorsunuz. Başka bir yerde kendi ayrı işlevlerinizi oluşturun.
rooby

-2

Bu yöntemi deneyin:

var a = "anan güzel mi?";
if (a.endsWith("?"))   a = a.slice(0, -1);  
document.body.innerHTML = a;


1
Neden? Bu ne yapar? O nasıl çalışır? SO'da yalnızca kod yanıtları düşük kaliteli olarak kabul edilir. Cevabınızı OP ve gelecekteki ziyaretçilerin ondan öğrenebilmesi için açıklayın.
Panik Yapmayın
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.