Teilen Sie die Sätze durch ',' und entfernen Sie die umgebenden Leerzeichen

82

Ich habe diesen Code:

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"]

Sieht so aus, als ob die gesamte Zeichenfolge abgeglichen wurde, aber wohin ist sie "b"gegangen? Ich würde eher erwarten zu bekommen:

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

damit kann ich m.shift()mit einem ergebnis wie s.split(',')aber auch mit entfernten Leerzeichen fertig werden.

Habe ich einen Fehler im regulären Ausdruck oder verstehe ich ihn falsch String.prototype.match?

meandre
quelle
Als Randnotiz {0,}ist das gleiche wie *.
Pimvdb
gut, skann auch sein ' a, c'oder'a,b,c d e, f'
meandre
Ich werde Leerzeichen in \ s ändern
meandre

Antworten:

190

Hier ist eine ziemlich einfache und unkomplizierte Möglichkeit, dies zu tun, ohne einen komplexen regulären Ausdruck zu benötigen.

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

Der native .mapwird ab IE9 unterstützt: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map


Oder in ES6 + wird es noch kürzer:

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

Und zur Vervollständigung hier in Typescript mit Tippinformationen

var arr: string[] = str.split(",").map((item: string) => item.trim());
CBarr
quelle
4
Um wählerisch zu sein, können Sie die Klammern um das Kartenargument beseitigen: var arr = str.split(",").map(item=>item.trim());
David Jones
Ich bin mit @DavidJones in diesem Fall. Wenn Sie Ihre Antwort ändern, wäre das großartig. Hat mir sehr für meinen Fall geholfen, danke Jungs!
Bereits
Ja, guter Punkt - Antwort aktualisiert, um dies widerzuspiegeln! Ich persönlich füge jedoch immer die Klammern hinzu, da ich normalerweise Typoskript schreibe, und ich möchte die expliziten Typinformationen bereitstellen, damit Sie immer auf einen Blick wissen, was etwas ist.
CBarr
Dies ist eine großartige Antwort, Chris.
zyklisch
Einfach und das Beste !!
Rahul Sonwanshi
21

Sie können dies ohne komplexe reguläre Ausdrücke versuchen.

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

xfg
quelle
15

Kurze Antwort: Verwenden m = s.match(/[^ ,]/g);


Ihr RE funktioniert nicht wie erwartet, da die letzte Gruppe mit der letzten Übereinstimmung übereinstimmt (= c). Wenn Sie dies weglassen {1,}$, wird die zurückgegebene Übereinstimmung angezeigt " a , b ", "a", "b". Kurz gesagt, Ihr RegExp gibt so viele Übereinstimmungen wie angegebene Gruppen zurück, es sei denn, Sie verwenden ein globalFlag /g. In diesem Fall enthält die zurückgegebene Liste Verweise auf alle übereinstimmenden Teilzeichenfolgen.

Verwenden Sie:

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

Dieses Ersetzen ersetzt jedes Komma ( ,), Anfang ( ^) und Ende ( $), umgeben von Leerzeichen, durch das ursprüngliche Zeichen ( commaoder nichts).

Wenn Sie ein Array erhalten möchten, verwenden Sie:

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

Dieser RE schneidet die Zeichenfolge ab (entfernt alle Leerzeichen am Anfang und Ende und teilt die Zeichenfolge dann durch <any whitespace>,<any whitespace>. Beachten Sie, dass Leerzeichen auch Zeilenumbrüche und Tabulatoren enthalten. Wenn Sie nur Leerzeichen verwenden möchten, verwenden Sie stattdessen ein Leerzeichen ( ) \s.

Rob W.
quelle
@ Andrew Ich habe die Erklärung Ihres RE erweitert. Siehe mein zweites Beispiel für eine splitMethode.
Rob W
Ich habe es bereits als Kommentar zu einer anderen Antwort gepostet. Ich frage mich, kann ich es mit einem regulären Ausdruck und einer Operation tun oder js regulärer Ausdruck ist nicht klug genug?
Meandre
@ Andrew Ja, einfach benutzen s.match(/[^ ,]+/g). Wie oben in meiner Antwort erwähnt, /gist das das globale Flag, das alle übereinstimmenden Teilzeichenfolgen zurückgibt.
Rob W
@ Andrew: Eine Erfassungsgruppe erstellt eine Übereinstimmung, unabhängig davon, wie viele Quantifizierer Sie hinzufügen. Wenn Sie vergleichen wollen a, bund cbrauchen Sie drei Paare von Klammern (ohne (?:...)):/(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)$/
user123444555621
@RobW, s.match (/ [^,] + / g) funktioniert genau so, wie ich es brauche, bitte füge es deiner Antwort hinzu
meandre
13

ES6-Kurzform:

str.split(',').map(item=>item.trim())
Dieter Gribnitz
quelle
8

Sie können dies für Ihren Zweck tun.
BEARBEITEN : Entfernen der zweiten Ersetzung, wie in den Kommentaren vorgeschlagen. s.replace(/^\s*|\s*$/g,'').split(/\s*,\s*/)
Zuerst wird replacedie Zeichenfolge abgeschnitten und dann wird die splitFunktion aufgeteilt '\s*,\s*'. Dies gibt Ausgabe ["a", "b", "c"]bei Eingabe " a , b , c "

Warum Ihr regulärer Ausdruck "b" nicht erfasst, wiederholen Sie eine erfasste Gruppe, sodass nur das letzte Vorkommen erfasst wird. Mehr dazu hier http://www.regular-expressions.info/captureall.html

Narendra Yadala
quelle
Ich möchte nicht alle Leerzeichen löschen, nur um Kommas oder am Anfang / Ende einer Zeichenfolge
Meandre
@ Andrew ist das nicht alles Whitespaces? oder hast du sätze, die du teilen möchtest?
David Hellsing
s.replace (/ ^ \ s * /, '') .replace (/ \ s * $ /, '') .split (/ \ s *, \ s * /) kann dies tun
meandre
@ Andrew Die Antwort wurde entsprechend Ihren Anforderungen geändert.
Narendra Yadala
6

Also ging ich schließlich mit /(?=\S)[^,]+?(?=\s*(,|$))/g, was genau das bietet, was ich brauche: alle durch ',' geteilten Sätze ohne umgebende Leerzeichen.

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

Danke vielmals!

meandre
quelle
Hier ist die Bedeutung, wie ich sie verstehe. Bitte korrigieren Sie mich, wenn ich nicht Recht habe: (?=\S)- Beginnen Sie mit der Erfassung nur, wenn kein Leerzeichen vor Ihnen steht. [^,]+Erfassen Sie so viele Nicht-Kommas wie möglich. ?Erfassen Sie jedoch nicht, was von der nächsten Gruppe erfasst werden kann. (?=\s*(,|$))Erfassen Sie alle Leerzeichen zuvor ein Komma oder Ende der Zeichenfolge /g- wiederholen Sie die gesamte Zeichenfolge
bedeuten Sie den
1

Wenn Sie weiterhin reguläre Ausdrücke verwenden möchten, halten Sie den Code einfach und ohne Verwendung von ES6:

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

1 - Ersetzen Sie alle Leerzeichen (/ / g) durch leere Zeichenfolgen ('')

2 - Teilen Sie es dann in ein Array auf

Et voila

AlbertSY
quelle
Dies ist die beste und am wenigsten komplizierte Antwort.
Blazes