Birden çok boşluğu tek bir boşlukla değiştirmek için normal ifade


510

Gibi bir dize verildi:

"Köpeğin uzun bir kuyruğu var ve KIRMIZI!"

Boşlukları yalnızca bir boşluk maksimumda tutmak için ne tür jQuery veya JavaScript büyüsü kullanılabilir?

Hedef:

"Köpeğin uzun bir kuyruğu var ve KIRMIZI!"

4
Beyaz boşluk sekme karakterleriyle de eşleşmek istiyor musunuz?
Chris Farmer

@Chris, Evet lütfen, harika soru .... Tüm bu farklı cevaplarla, hangisinin en etkili çözüm olduğunu nasıl bilebiliriz?
Aralık'ta

2
Aşağıdaki herkes haklı, ancak bu en optimize edilmiş normal ifade: str.replace(/ +(?= )/g,'');gerekmeyen hiçbir şeyi değiştirmiyorsunuz.
Evan Carroll

2
Performansta gözle görülür bir fark olmayacak. Her zaman profil oluşturabilirsin, ama buna değeceğinden şüpheliyim. Ben en açık olanı seçerdim.
09:15

@EvanCarroll: Doğru değil - en azından Firefox'ta. Bu sürüm önemli ölçüde yavaş çalışıyor. Yanıtımda profilleme sonuçlarına bakın (aşağıda).
Edward Loper

Yanıtlar:


937

Ayrıca sadece değiştirmek, vs kapak sekmeler satırbaşıyla, istediğiniz düşünüldüğünde \s\s+ile ' ':

string = string.replace(/\s\s+/g, ' ');

Gerçekten yalnızca boşlukları (ve böylece sekmeleri, yeni satırları vb.) Kapsamak istiyorsanız, şunu yapın:

string = string.replace(/  +/g, ' ');

4
Normal ifadeye 'g' bayrağı da eklemeniz gerekir.
Rafael

6
Bir sekme veya satırsonu yerine bir boşluk gerektiğinde bu çalışmaz. Sağ? / \ s + / çalışır.
Fabian

3
gibi bir işlev olarak sizin için daha iyi olabilirfunction removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}
Math chiller

5
@Ethan: JS bunun için yerleşik bir işlevi vardır: trim(). Normal ifadeden daha hızlı. Sadece yapabilirsin string.trim().replace(/\s\s+/g, ' ');ya da string.replace(/\s\s+/g, ' ').trim();.
BalusC

4
/\s\s+/gve /\s{2,}/gbirbirine bitişik en az iki tane yoksa beyaz karakterlerle eşleşmeyin, örneğin \ t \ t ile eşleşecek, ancak tek \ t ile eşleşmeyecektir. string.replace(/\s+/g, ' ')tüm tek ve çoklu beyaz karakter alt dizeleriyle eşleşecek ve yerine tek boşluk bırakılacaktır.
remyActual

159

Performansla ilgilendiğiniz için bunları kundakçı ile profilli yaptım. İşte elde ettiğim sonuçlar:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

Bu Firefox'ta, 100k dize değiştirmeleri çalışıyor.

Performansın bir sorun olduğunu düşünüyorsanız, firebug ile kendi profilleme testlerinizi yapmanızı öneririm. İnsanlar programlarındaki darboğazların nerede olduğunu tahmin etmede kötü bir şekilde kötüdür.

(Ayrıca, IE 8'in geliştirici araç çubuğunda yerleşik bir profil oluşturucu olduğuna dikkat edin - IE'de performansın nasıl olduğunu kontrol etmeye değer olabilir.)


5
jsperf.com/removing-multiple-spaces Devam edin ve JSPerf! Son yöntem; ( / +(?= )/g, ' ');IE9 başarısız, çift boşluk bırakır: "Foo Bar Baz".replace(/ +(?= )/g, ' ');->"Foo Bar Baz"
Nenotlep

nasıl çok fark bw 1 ve 2. çizgi
Vivek Panday

@VivekPanday - Bunun ikinci satırın yalnızca çift boşluk örneklerini tek bir boşlukla değiştirdiğini, birincisi de herhangi bir alanı bir boşlukla değiştirdiğini düşünüyorum. Bu arama sırasında zamandan tasarruf veya gerçek değiştirme olsun, bilmiyorum.
Maloric

Bu, ilk ve sondaki boşlukları kaldırmaz. Bunun için bu cevaba bakınız .
Ethan

Hızı düşürerek siparişe göre düzenlenmiştir. Vivek'in ve Maloric'in yorumları 380 ms ve 790 msn çizgileriyle ilgilidir.
Skippy le Grand Gourou

43
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

DÜZENLEME: Her türlü boşluk karakterini değiştirmek isterseniz en etkili yol şöyle olur:

str = str.replace(/\s{2,}/g,' ');

Komik olan test dizenizde iki boşluk bile yok.
Josh Stodola

Yakın zamanda ne
bulduğumu fark ettiniz

2
Nedense bu çalışmıyor ... Bir sürü "& nbsp;" gösteriliyor ... Muhtemelen CKEDITOR nedeniyle ...
AnApprentice

K, JQUERY'nin metninin () işleri karıştırdığını ortaya koyuyor. sabit - teşekkürler!
Çırak

16

Tüm alan karakterlerini hedefleyecek olsa da bu bir çözümdür :

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Düzenleme : 1 veya daha fazla alanı izleyen bir alanı hedeflediğinden, bu muhtemelen daha iyidir:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Alternatif yöntem:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

Tek /\s+/başına kullanmadım , çünkü bu, 1 karakteri kapsayan boşlukları birden çok kez değiştirir ve gerektiğinden daha fazlasını hedeflediğinden daha az verimli olabilir.

Bu hatalardan herhangi birini derinden test etmedim.

Ayrıca, dize değiştirme yapacaksanız, değişkeni / özelliği kendi yerine yeniden atamayı unutmayın, örn:

var string = 'foo'
string = string.replace('foo', '')

JQuery.prototype.text kullanma:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )

1
Birincisi tamamen anlamsızdır, \ s \ s +, bir \ s ardından bir veya daha fazla \ s + anlamına gelir, bu da tek bir \ s + 'ya düşürülebilir, ikinci örnek daha doğrudur, çünkü sadece çift boşlukları değiştirmek istiyoruz, değil yeni satırlar, üçüncüsü daha optimize edilmiştir çünkü yalnızca 2+ boşluklu örnekler için geçerlidir. Ancak str.replace (/ + (? =) / G, '');, yalnızca 2+ boşluk içeren örnekler için geçerlidir, ancak boşluk adımıyla bir alanın üzerine yazmaktan tasarruf sağlar.
Evan Carroll

4
EvanCarroll Eğer başarısız \ s \ s + \ s + 'ya kesinlikle farklı olduğu için. \ s \ s + '\ t \ t' veya '\ t \ t \ t' ile eşleşir ancak '\ t' ile eşleşmez. Ve hepsi bu, her f-en tek boşluk karakterini değiştirmek istemezsiniz.
18'te bekle

Yaparım. Tam metin araması (ve snippet-display) için kullanılır: Lütfen rastgele sekmeler, kesiciler veya nesneler yok, lütfen.
T4NK3R

13

Bu yöntem var, daha iyi bir isim eksikliği için Derp yöntemi diyorum.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

JSPerf'de çalıştırmak şaşırtıcı sonuçlar verir.


2
Eğer ortaya çıkarsa cehennem gibi
utanacağım

Test davası vermek ... Mükemmel cevap!
Oytun

2
Bu benim günüm :-) Komik "derping" genellikle tüm "zeki" olmaktan daha iyi çalışır. "Derp split" kıçını tekmelemiş gibi görünüyor. Yine de, yükselmeyi hak ediyor.
Fred Gandt

13

Daha sağlam bir yöntem: Bu , varsa ilk ve sondaki boşlukları da kaldırmaya özen gösterir . Örneğin:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Örneğinizde bu boşluklar yoktu, ancak onlar da çok yaygın bir senaryodur ve kabul edilen cevap, bunları yalnızca tek boşluklara kırpmaktı: "Genellikle ..."!


3
Bu kalıbı PHP üzerinde kullandım ve çalışıyor. $ parts = preg_split ("/ ^ \ s + | \ s + $ | \ s + (? = \ s) /", "Avenida Tancredo Neves, 745 Piso Térreo Sala");
Bruno Ribeiro

11

Daha sağlam:

işlev düzeltme (word)
{
    word = word.replace (/ [^ \ x21- \ x7E] + / g, ''); // yazdırılmayan grafikleri boşluk olarak değiştirin
    dönüş word.replace (/ ^ \ s + | \ s + $ / g, ''); // öndeki / arkadaki boşlukları kaldır
}

8

öneririm

string = string.replace(/ +/g," ");

sadece alanlar için
VEYA

string = string.replace(/(\s)+/g,"$1");

birden çok dönüşü tek bir dönüşe dönüştürmek için.


6

Partiye geç kaldığımı biliyorum, ama güzel bir çözüm keşfettim.

İşte burada:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');

6

Replace kullanmak istemiyorsanız alternatif bir çözüm (replace javascript kullanmadan bir dizedeki boşlukları değiştirin)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;
str = str.split(rule).join(" "); 
document.write(str);

5

Yeni başlayanlar için kapsamlı şifrelenmemiş cevap et al.

Bu, benim gibi çalışmayan bazılarınız tarafından yazılan senaryoları test eden benim gibi tüm mankenler içindir.

Aşağıdaki 3 örnek, aşağıdaki 3 web sitesindeki (tümü mükemmel çalışan) özel karakterleri VE fazladan boşlukları kaldırmak için attığım adımlardır {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} böylece bunların mükemmel çalıştığını biliyorum.

Bunları bir seferde 50'den fazla ve NO problemi ile birlikte zincirledik.

// Bu özel karakterler + 0-9 kaldırıldı ve sadece harflere izin veriyor (büyük ve LOWER harf)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// Bu özel karakterleri sildi ve sadece harflere (üst ve ALT harf) ve 0-9 VE boşluklarına izin verir

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// Bu özel karakterleri kaldırdı ve sadece harflere (üst ve ALT harf) ve 0-9 VE boşluklarına izin veriyor // Sonundaki .replace (/ \ s \ s + / g, "") aşırı boşlukları kaldırıyor // tek tırnak kullanılan, işe yaramadı.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

:: SONRAKİ :: # 3 olarak kaydet a .js// mayın NoDoubles.js olarak adlandırdım

:: SONRAKİ :: JS'nizi sayfanıza ekleyin

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Bunu form alanınıza ekleyin :: gibi

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Öyle görünüyor ki

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

Bu, özel karakterleri kaldıracak, tek boşluklara izin verecek ve fazladan boşluk kaldıracaktır.


Burada neler oluyor? Biçimlendirme çok, çok bozuk görünüyor.
Nenotlep


1
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

Veya sekmeleri de değiştirmek istiyorsanız:

var replaced = string.replace(/\s+/g, " ");

1
+ kullanımı daha temiz görünüyor, ancak tek boşlukları tek boşluklarla değiştirecek, biraz gereksiz ve emin değilim ama çok daha uzun bir metinle performans sorunları oluşturabilir.
ahmetunal

Çalışacak en kısa, en basit çözümü kullanma eğilimindeyim ve sadece çok büyük bir dizeyle eşleşmem gerektiğini bildiğimde bu tür bir optimizasyon konusunda endişeleniyorum, bu noktada gerçekten hangi çözümleri görmek daha hızlı ol. Test etmeden en hızlı neyin olacağını önceden tahmin etmek zor olabilir; Örneğin, JavaScript yorumlayıcılarında bazı karmaşık düzenli ifadeler hızlı bir JIT derlemeli uygulamadan yavaş yorumlanan bir uygulamaya geçmenize neden olur.
Brian Campbell

1

Jquery temelde bu "FOo Bar" gibi bir şeyi "FOo Bar" a çeviren trim () fonksiyonuna sahiptir.

var string = "  My     String with  Multiple lines    ";
string.trim(); // output "My String with Multiple lines"

Çok daha kullanışlıdır, çünkü dizenin başında ve sonunda boş alanları otomatik olarak kaldırır. Normal ifade gerekmez.


3
Dediğiniz gibi, trim () , dizenin başında ve sonunda boş boşlukları kaldırır , ancak dizenin ortasında değil, bu nedenle, bu durumda çalışmaz, çıktı yalnızca satırları". api.jquery.com/jQuery.trim
egvaldes

1

replace kullanılmazsa, string = string.split (/ \ W + /);


0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');

0

Sed system komutunun yardımıyla açıklanan aşağıdaki normal ifadeyi kullanabiliriz. Benzer regex diğer dillerde ve platformlarda kullanılabilir.

Metni bir dosyaya söyle testi ekle

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

Tüm beyaz boşlukları tek boşlukla değiştirmek için aşağıdaki normal ifadeyi kullanabiliriz

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

Umarım bu amaca hizmet eder


0

Birden çok boşluğu tek bir boşlukla değiştirmek için bunu deneyin.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

Devamını oku @ Birden Çok Boşluğu Tek Boşlukla Değiştirme


0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

sonuç:

"xxx df dfvdfv df dfv"

0

Daha fazla kontrol için değeri işlemek üzere geri arama yerine kullanabilirsiniz.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"

0

Bu komut dosyası, sözcükler ve kırpmalar arasındaki beyaz boşlukları (birden çok boşluk, sekme, döndürme vb.) Kaldırır:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};

0

'fare işaretçisi dokunma'. değiştirin (/ ^ \ s + | \ s + $ | (\ s) + / g, "$ 1") hile yapmalı!


0

Normal ifadeyi kullanmamız gerektiğini biliyorum, ancak bir röportaj sırasında REGEX KULLANMADAN yapmam istendi.

@slightlytyler aşağıdaki yaklaşımla gelmeme yardımcı oldu.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));


düşünün: console.log (testStr.split ("") .filter (s => s.length) .join (""))
dpjanes
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.