Cümleleri ',' ile bölün ve etrafındaki boşlukları kaldırın


85

Bu koda sahibim:

var r = /(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*){0,}$/
var s = "   a   ,  b  , c "
var m = s.match(r)
m => ["   a   ,  b  , c ", "a", "c"]

Görünüşe göre dizenin tamamı eşleşmiş, ama nereye "b"gitti? Şunu almayı tercih ederim:

["   a   ,  b  , c ", "a", "b", "c"]

böylece boşluklar kaldırılmış m.shift()gibi bir sonuçla s.split(',')da yapabilirim.

Normal ifadede bir hata mı var yoksa yanlış String.prototype.matchmı anlıyorum ?


Bir yan not olarak, {0,}ile aynıdır *.
— pimvdb

iyi, saynı zamanda ' a, c'veya olabilir'a,b,c d e, f'
— meandre

boşlukları \ s olarak değiştireceğim
— meandre

Yanıtlar:


195

İşte bunu karmaşık bir düzenli ifadeye ihtiyaç duymadan yapmanın oldukça basit ve anlaşılır bir yolu.

var str = "   a   ,  b  , c "
var arr = str.split(",").map(function(item) {
  return item.trim();
});
//arr = ["a", "b", "c"]

Yerel .map, IE9 ve üzeri sürümlerde desteklenir: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map


Veya ES6 + 'da daha da kısalır:

var arr = str.split(",").map(item => item.trim());

Ve tamamlanması için, burada yazım bilgileriyle birlikte Typescript'te

var arr: string[] = str.split(",").map((item: string) => item.trim());

4
Sadece seçici olmak için, harita tartışmasının etrafındaki parantezleri kaldırabilirsiniz: var arr = str.split(",").map(item=>item.trim());
— David Jones

Bu konuda @DavidJones ile birlikteyim. Cevabınızı değiştirirseniz çok iyi olur. Davam için bana çok yardımcı oldu, teşekkürler çocuklar!
— Zatentakenindeed

Evet iyi nokta - cevap bunu yansıtacak şekilde güncellendi! Genelde Typescript yazdığım için şahsen her zaman parantez ekliyorum ve açık tip bilgilerini vermeyi seviyorum, böylece bir şeyin ne olduğunu her zaman bir bakışta anlayabilirsiniz.
— CBarr

Bu harika bir cevap Chris.
— döngüsel

Basit ve en iyisi !!
— Rahul Sonwanshi

23

Bunu karmaşık normal ifadeler olmadan deneyebilirsiniz.

var arr = "   a   ,  b  , c ".trim().split(/\s*,\s*/);
console.log(arr);


17

Kısa cevap: Kullan m = s.match(/[^ ,]/g);


RE'niz beklendiği gibi çalışmıyor çünkü son grup en son eşleşmeyle eşleşiyor (= c). Atlarsanız {1,}$, iade edilen maç olacaktır " a , b ", "a", "b". Kısacası, bir bayrak kullanmadığınız sürece , RegExp'iniz belirtilen gruplar kadar çok eşleşme döndürür . Bu durumda, döndürülen liste tüm eşleşen alt dizelere başvuruları tutar.global/g

Etkinize ulaşmak için şunları kullanın:

m = s.replace(/\s*(,|^|$)\s*/g, "$1");

Bu değiştirme , beyaz boşluklarla çevrili, orijinal karakterle ( veya hiçbir şeyle) her virgül ( ,), başlangıç ​​( ^) ve bitiş ( $) yerine geçer comma.

Bir dizi elde etmek istiyorsanız, şunu kullanın:

m = s.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/);

Bu RE, dizeyi keser (baştaki ve sondaki tüm beyaz boşlukları kaldırır, ardından dizeyi böler <any whitespace>,<any whitespace>. Beyaz boşluk karakterlerinin ayrıca yeni satırlar ve sekmeler içerdiğini unutmayın. Yalnızca boşluklara bağlı kalmak istiyorsanız, yerine boşluk ( ) kullanın\s .


@Andrew RE'nizin açıklamasını genişlettim. splitYöntem için ikinci örneğime bakın .
— Rob W

zaten başka bir cevaba yorum olarak gönderdim. Merak ediyorum, bunu bir regexp ve bir işlemle yapabilir miyim yoksa js regexp yeterince akıllı değil mi?
— meandre

@Andrew Evet, sadece kullanın s.match(/[^ ,]+/g). Cevabımın en üstünde belirtildiği gibi /g, eşleşen tüm alt dizeleri döndüren global bayraktır.
— Rob W

@Andrew: Bir yakalama grubu, kaç miktar belirleyici eklerseniz ekleyin, bir eşleşme oluşturur. Eğer eşleşme istiyorsanız a, bve c, siz (dahil değil parantez üç çift ihtiyacımız (?:...):)/(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)$/
— user123444555621

@RobW, s.match (/ [^,] + / g) tam olarak ihtiyacım olduğu gibi çalışıyor, lütfen cevabınıza ekleyin
— meandre


9

Bunu amacınız için yapabilirsiniz
DÜZENLE : Yorumlarda önerildiği gibi ikinci değiştirmeyi kaldırma. s.replace(/^\s*|\s*$/g,'').split(/\s*,\s*/)
Önce replacedizeyi kırpar ve ardından splitişlev bölünür '\s*,\s*'. Bu ["a", "b", "c"], girişte çıktı verir" a , b , c "

Normal ifadenizin neden 'b'yi yakalamadığına gelince, yakalanan bir grubu tekrarlıyorsunuz, bu nedenle yalnızca son geçtiği yer yakalanır. Bununla ilgili daha fazla bilgiyi burada http://www.regular-expressions.info/captureall.html


tüm beyaz boşlukları yalnızca virgüllerin etrafında veya bir dizenin başında / sonunda silmek istemiyorum
— meandre

@Andrew tüm boşluklar değil mi? veya bölmek istediğin cümleler var mı?
— David Hellsing

s.replace (/ ^ \ s * /, '') .replace (/ \ s * $ /, '') .split (/ \ s *, \ s * /) bunu yapabilir
— meandre

@Andrew Gereksinimlerinize göre cevabı değiştirdi.
— Narendra Yadala

7

bu yüzden nihayet gittim /(?=\S)[^,]+?(?=\s*(,|$))/g, tam da ihtiyacım olanı sağlıyor: tüm cümleler çevreleyen boşluklar olmadan ',' ile bölünmüş.

'       a,    OMG     abc b a b, d o WTF        foo     '.
  match( /(?=\S)[^,]+?(?=\s*(,|$))/g )
=> ["a", "OMG     abc b a b", "d o WTF        foo"]

çok teşekkürler!


İşte anladığım anlamıyla anlamı. haklı değilsem lütfen beni düzeltin: (?=\S)- yalnızca önünde boşluk olmadığında yakalamaya başlayın [^,]+- mümkün olduğunca çok 'virgül olmayanları' ?yakalayın - ancak sonraki grup tarafından yakalanabilecekleri (?=\s*(,|$))yakalamayın - daha önce tüm boşlukları yakalayın virgül veya dizenin sonu /g- tüm dizeyi tekrarlayın
— meandre

2

Normal ifadeyi kullanmaya devam etmek istiyorsanız, kodu basit tutun ve ES6 kullanmadan:

s.replace(/ /g, '').split(",")

1 - Tüm boşlukları (/ / g) boş dizelerle ('') değiştirin

2 - Ardından bir diziye bölün

Et voila


Bu en iyi, en az karmaşık cevaptır.
— Alevler
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.