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.