Bash Regex-Kuriosität bei Verwendung des Operators = ~

308
user584029

Betrachten Sie diesen Code:

s1="1,2,3,4"; \ s2="1,2,3"; \ sP='^(([1-9][0-9],))$'; \ [[ "$," =~ $sP ]] && echo "\$s1 matches"; \ [[ "$," =~ $sP ]] && echo "\$s2 matches, but why?" 

Ich bin verblüfft, warum die zweite Saite übereinstimmt. Ist meine Regex fehlerhaft? Es soll entweder 2 oder 4 "Elemente" passen.

2
Da ich meine Frage nicht bearbeiten kann, folgt Folgendes: Ich möchte entweder 1, 2 oder 4 Instanzen der Ziffernfolge abgleichen (vergaß die 1, die den "kombinierten" inneren Quantifizierer von erfordert). user584029 vor 8 Jahren 0
Der Hauptpunkt meiner Frage sollte lauten: "Warum funktioniert das nicht so?" Was habe ich verpasst? user584029 vor 8 Jahren 0

1 Antwort auf die Frage

0
Jay jargot

Um entweder 1, 2 oder 4 Elemente übereinzustimmen, muss der ERE wie folgt geändert werden:

s1="1,2,3,4" ;\ s2="1,2,3" ;\ s3="1" ;\ sP='^[1-9][0-9],$|^(([1-9][0-9],))$' ;\ [[ "$," =~ $sP ]] && printf "\$s1, matches\n" ;\ [[ "$," =~ $sP ]] || printf "\$s2, does not match\n" ;\ [[ "$," =~ $sP ]] && printf "\$s3 matches\n" 

Ihr ursprüngliches ERE könnte iterativ beschrieben werden:

[1-9][0-9], entspricht 1 oder 2 oder 3 oder 432 usw.

([1-9][0-9],) trifft auf eine einzelne oder zwei aufeinanderfolgende Sequenzen, die oben beschrieben wurden: 1 oder 3 oder 1,2 oder 10 oder 10,432 usw.

(([1-9][0-9],)) entspricht einem oder zwei Vorkommen der letzten Sequenz 1 oder 1,2 oder 1,2,3 usw.

Jay natürlich; Entschuldigung, ich habe das in meiner Frage gemischt, und das Beispiel zeigt nicht, dass: Ich möchte entweder 1, 2 oder 4 Instanzen zusammenbringen (vergaß die 1, die den "kombinierten" inneren Quantifizierer von ' '); Will auch die ursprüngliche Frage kommentieren ... user584029 vor 8 Jahren 0
@ user584029 Der Anfang der Antwort wurde mit einem neuen ERE aktualisiert. Es stimmt mit s1 und "1" überein, aber nicht mit s2. Jay jargot vor 8 Jahren 0
Ja, danke für das Hinzufügen von "... 1 oder 2 oder 4 Sequenz ..."; Ich habe nicht genug geklärt - ich suche mehr nach einer Erklärung für den "Warum funktioniert es nicht" (das ursprüngliche) Weg - um sicher zu sein, dass ich EREs nicht missverstanden habe. user584029 vor 8 Jahren 0
[@] Jay jargot Die letzte Zeile lässt mich nicht völlig überzeugt sein: Ihr innerer Teil (wie in der vorletzten Zeile) ergibt entweder eine Sequenz der Art "d ... d" oder eine Sequenz der Art "d ... d, d ... d, "; Wenn eine dieser Sequenzen einmal oder zweimal auftritt, sollte (1) "d ... d" oder (2) "d ... d, d ... d" oder (3) "d ..." d, d ... d, d ... d, d ... d ", wobei (2) auf zwei Arten konstruiert werden könnte. Vielleicht habe ich EREs auch nicht voll ausgereizt ... Übrigens: printf ist besser! user584029 vor 8 Jahren 0
@ user584029 der ERE wird gemacht oder 2 Teile werden mit `|` begrenzt. Auf der linken Seite stimmt es nur mit einer einzigen Sequenz überein. Auf der rechten Seite passt es zu 2 oder 4 usw. Jay jargot vor 8 Jahren 0
Ja, Ihr ERE wird mit "|" kompensiert, aber nicht mit meinem. Ich frage mich nur, ob es falsch ist, die Logik meines vorherigen Kommentars auf den (meinen) ursprünglichen Regex anzuwenden. Meine Erwartung war, dass es nicht der dreiteiligen Sequenz entsprechen würde. user584029 vor 8 Jahren 0
Bei Ihrem ERE ergibt der innere Teil entweder ein "n" oder "n, n", so dass diese Sequenz ein- oder zweimal auftreten kann, wobei "n" oder "n, n" oder "n, n" auftreten. n, ` Jay jargot vor 8 Jahren 0
Sicher? Der innere Teil, der entweder 1 oder 2 Untersequenzen ergibt, die entweder einmal oder zweimal vorkommen können, sollte eine Folge von 1 oder 2 oder 4 "Elementen" ergeben: 1 * 1 oder 2 * 1 oder 1 * 2 oder 2 * 2 (wobei 2 Elemente sind auf zwei verschiedene Arten erreicht, wie in meinem zweiten Kommentar beschrieben. user584029 vor 8 Jahren 0
@ user584029 Das Beste ist, Strings gegen die ERE zu testen, um Fehler zu beheben. Jay jargot vor 8 Jahren 0
nach einiger Zeit wieder aufgegriffen und schließlich das Problem in meiner Argumentation sehen; Mit meinem Regex sind 3 Ziffernfolgen (ds) möglich, da die erste innere Übereinstimmung 1 oder 2 ds, die zweite innere Übereinstimmung 1 oder 2 ds ergeben kann; Ich nahm fälschlicherweise an, dass die erste innere Übereinstimmung, die 1 ds Übereinstimmung ergibt, irgendwie die zweite innere Übereinstimmung "einschränken" würde, um auch 1 ds zu erhalten; Mein Ziel war es, das Ziffernfolgenmuster nicht zu wiederholen, was möglicherweise nicht möglich ist. In der Tat löst das von @jay jargot vorgeschlagene Muster die Aufgabe user584029 vor 7 Jahren 0