Regex für durch Kommas getrennte Liste

75

Was ist der reguläre Ausdruck, um eine durch Kommas getrennte Liste wie diese zu validieren:

12365, 45236, 458, 1, 99996332, ......
everLearningStudent
quelle
Wird es jemals entkommene Charaktere geben, wie:12365,45236,"This is a \"test."
ceejayoz
7
Warum muss es ein Regex sein? Abhängig von der Sprache ist es möglicherweise besser, einen integrierten CSV-Parser zu verwenden.
Mark Biek

Antworten:

110

Ich schlage vor, dass Sie Folgendes tun:

(\d+)(,\s*\d+)*

Dies würde für eine Liste mit 1 oder mehr Elementen funktionieren.

Asaph
quelle
1
Sie haben Recht, ich musste einen ersten Charakter
entfernen,
@ondrobaco: Du inspizierst wahrscheinlich nur die erste Matchgruppe. Die nächste Matchgruppe enthält den Rest der Liste.
Asaph
4
Die obige Lösung validiert keine leere Liste. (^$)|(^(\d+)(,\s*\d+)*$)könnte aber funktionieren.
Chris
1
@Val: Das Problem mit Ihrer Lösung ist, dass sie nicht mit Listen übereinstimmt, die überhaupt keine Kommas haben, wie z. B. "1"oder "12345". Diese Liste enthält nicht mehrere Elemente, daher haben sie keine Kommas. Und Ihre Regex (\d+,)*schreibt vor, dass auf jede Zahl ein Komma folgt.
Asaph
4
Wie würde man jedes Element abgleichen / extrahieren (mit einem regulären Ausdruck)?
Gustavo Puma
19

Dieser reguläre Ausdruck extrahiert ein Element aus einer durch Kommas getrennten Liste, unabhängig vom Inhalt:

(.+?)(?:,|$)

Wenn Sie nur das Komma durch etwas anderes ersetzen, sollte es für jedes Trennzeichen funktionieren.

KP
quelle
Extrahiert es mehr als ein Element?
Paranza
1
Um mit Leerzeichen nach den Kommas umzugehen, wie im OP, schlage ich diese geringfügige Änderung vor: (.+?)(?:,\s*|$)
Chad Cloman
1
@paranza - Ja, dies extrahiert mehr als ein Element, aber nur, wenn der globale Abgleich aktiviert ist. Wenn die von Ihnen verwendete Funktion alle Übereinstimmungen anstelle nur des ersten zurückgibt. Früher haben Sie dies getan, indem Sie nach dem abschließenden Schrägstrich ein "g" gesetzt haben (z. B. /expr/g), aber anscheinend ist das nicht alles Standard. In PHP müssen Sie zum Beispiel preg_match_all()statt verwenden preg_match(). Andere Arten von Regex haben andere Möglichkeiten.
Chad Cloman
10

Es hängt ein wenig von Ihren genauen Anforderungen ab. Ich gehe davon aus: Alle Zahlen, jede Länge, Zahlen dürfen keine führenden Nullen haben und keine Kommas oder Dezimalstellen enthalten. einzelne Zahlen werden immer durch ein Komma und dann durch ein Leerzeichen getrennt, und die letzte Zahl hat KEIN Komma und kein Leerzeichen danach. Jedes dieser Fehler würde die Lösung vereinfachen.

([1-9] [0-9] *, []) * [1-9] [0-9] *

So habe ich das mental aufgebaut:

[0-9]  any digit.
[1-9][0-9]*  leading non-zero digit followed by any number of digits
[1-9][0-9]*, as above, followed by a comma
[1-9][0-9]*[ ]  as above, followed by a space
([1-9][0-9]*[ ])*  as above, repeated 0 or more times
([1-9][0-9]*[ ])*[1-9][0-9]*  as above, with a final number that doesn't have a comma.
mcherm
quelle
Ich fand diese Antwort wirklich nützlich, brauchte nur eine kleine Änderung, um Leerzeichen vor und nach dem Komma zu akzeptieren ([1-9][0-9]*[ ]*,[ ]*)*[1-9][0-9]*... vielleicht findet jemand diese nützlich
pollirrata
Mir gefällt dieses Beispiel am besten. Wie würde ich danach Zeilenumbrüche zulassen?
Justinpees
7

Ordnen Sie doppelte durch Kommas getrennte Elemente zu:

(?<=,|^)([^,]*)(,\1)+(?=,|$)

Referenz .

Dieser reguläre Ausdruck kann verwendet werden, um die Werte einer durch Kommas getrennten Liste aufzuteilen. Listenelemente können in Anführungszeichen, nicht in Anführungszeichen oder leer stehen. Kommas in einem Anführungszeichenpaar stimmen nicht überein.

,(?!(?<=(?:^|,)\s*"(?:[^"]|""|\\")*,)(?:[^"]|""|\\")*"\s*(?:,|$))

Referenz .

Madcolor
quelle
Was genau macht das Pipe-Symbol (|) dort? Es ist das einzige Symbol, das auf der Seite, auf die Sie verlinken, nicht erklärt wurde, und ich kann es nicht verstehen.
Thomas Vander Stichele
@ ThomasVanderStichele: Es ist für den Wechsel. (foo|bar)passt entweder foooder bar. Für weitere Informationen: reguläre-Ausdrücke.info
Amal Murali
5
/^\d+(?:, ?\d+)*$/
w35l3y
quelle
4

Dieser lehnt überflüssige Kommas am Anfang oder Ende der Zeile ab, wenn dies für Sie wichtig ist.

((, )?(^)?(possible|value|patterns))*

Ersetzen Sie possible|value|patternsdurch einen regulären Ausdruck, der Ihren zulässigen Werten entspricht.

Will Hains
quelle
2

Ich habe dies für eine Liste von Elementen verwendet, die alphanumerisch ohne Unterstriche an der Vorderseite jedes Elements sein mussten.

^(([0-9a-zA-Z][0-9a-zA-Z_]*)([,][0-9a-zA-Z][0-9a-zA-Z_]*)*)$
PPPaul
quelle
1

Möglicherweise möchten Sie die Sprache nur aus Sicherheitsgründen angeben, aber

(\d+, ?)+(\d+)?

sollte funktionieren

David Berger
quelle
1
Diese Lösung schlägt für eine Liste fehl, die nur 1 Element enthält. Siehe meine Lösung unten.
Asaph
1

Ich hatte eine etwas andere Anforderung, ein verschlüsseltes Wörterbuch / eine Hashtabelle mit Kommas wie folgt zu analysieren:

"1=This is something, 2=This is something,,with an escaped comma, 3=This is something else"

Ich denke, dies ist eine elegante Lösung mit einem Trick, der viel Regex-Komplexität vermeidet:

if (string.IsNullOrEmpty(encodedValues))
{
    return null;
}
else
{
    var retVal = new Dictionary<int, string>();
    var reFields = new Regex(@"([0-9]+)\=(([A-Za-z0-9\s]|(,,))+),");
    foreach (Match match in reFields.Matches(encodedValues + ","))
    {
        var id = match.Groups[1].Value;
        var value = match.Groups[2].Value;
        retVal[int.Parse(id)] = value.Replace(",,", ",");
    }
    return retVal;
}

Ich denke, es kann mit einem Ausdruck wie @"([0-9]+),\s?"und Analyse auf die ursprüngliche Frage angepasst werden Groups[0].

Ich hoffe, es ist hilfreich für jemanden und danke für die Tipps, wie man es in die Nähe bringt, besonders für Asaph!

alpsystems.com
quelle
1

Verwenden Sie splitin JavaScript, um zu helfen und auch negative Ziffern abzufangen:

'-1,2,-3'.match(/(-?\d+)(,\s*-?\d+)*/)[0].split(',');
// ["-1", "2", "-3"]
// may need trimming if digits are space-separated
crazy4groovy
quelle
0

Das Folgende stimmt mit jeder durch Kommas getrennten Kombination aus Wort, Ziffer und Leerzeichen überein

(((.)*,)*)(.)*
Aidan
quelle
Diese Regex ist nicht nützlich, wenn Sie durch Kommas getrennte Werte wünschen. Es erlaubt Wort; Wort; Wort ...
caravana_942