2013-04-28 9 views
22

Potrzebuję pomocy w dzieleniu ciągu znaków w javascriptie przez spację (""), ignorując spację w cudzysłowie.javascript podzieliła ciąg znaków według spacji, ale zignoruj ​​spację w cudzysłowach (zauważ, że nie należy również dzielić dwukropka)

Mam ten ciąg:

var str = 'Time:"Last 7 Days" Time:"Last 30 Days"'; 

spodziewałbym mój łańcuch zostanie podzielona na 2:

['Time:"Last 7 Days"', 'Time:"Last 30 Days"'] 

ale mój kod dzieli na 4:

['Time:', '"Last 7 Days"', 'Time:', '"Last 30 Days"'] 

to mój kod:

str.match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g); 

Dzięki!

+0

Chociaż powiązane pytanie _related_ , to _nie jest duplikatem: _Te_ pytanie jednoznacznie wymaga nie cytowanych ciągów, które bezpośrednio sąsiadują z podwójnym qu oted string (np. 'foo:" bar none "') do rozpoznania jako znacznik _single_ (a także nie wspomina o konieczności obsługi escaped cudzysłowów.) – mklement0

Odpowiedz

51
s = 'Time:"Last 7 Days" Time:"Last 30 Days"' 
s.match(/(?:[^\s"]+|"[^"]*")+/g) 

// -> ['Time:"Last 7 Days"', 'Time:"Last 30 Days"'] 

Poradnik:

(?:   # non-capturing group 
    [^\s"]+ # anything that's not a space or a double-quote 
    |   # or… 
    "   # opening double-quote 
    [^"]* # …followed by zero or more chacacters that are not a double-quote 
    "   # …closing double-quote 
)+   # each match is one or more of the things described in the group 

Okazuje się, aby naprawić swój pierwotny wyraz, wystarczy dodać + na grupy:

str.match(/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g) 
#      ^here. 
+1

To byłaby dobra odpowiedź, gdybyś wyjaśnił regularne wyrażenie. –

+0

po prostu najpierw to upuszczono. – kch

+0

Dzięki! Prace! i super szybka odpowiedź :-) – user1986447

0

ES6 rozwiązanie drugoplanowy:

  • Podziel przez spację, z wyjątkiem f lub wewnątrz cytuje
  • Usuwanie cytatów, ale nie dla BACKSLASH uciekły cytaty
  • Uciekł cytat stać cytat

Kod:

str.match(/\\?.|^$/g).reduce((p, c) => { 
     if(c === '"'){ 
      p.quote ^= 1; 
     }else if(!p.quote && c === ' '){ 
      p.a.push(''); 
     }else{ 
      p.a[p.a.length-1] += c.replace(/\\(.)/,"$1"); 
     } 
     return p; 
    }, {a: ['']}).a 

wyjściowa:

[ 'Time:Last 7 Days', 'Time:Last 30 Days' ] 
Powiązane problemy