2009-03-24 8 views
22

Ich möchte mit RegExp eine Zahl zwischen X und Y übereinstimmen. Ist das möglich?Wie tausche ich Zahlen zwischen X und Y mit regexp?

([0-9] +) wird mit einer beliebigen Zahl übereinstimmen. Wie kann ich eine Zahl zwischen beispielsweise 110 und 2234 finden?

+25

Ja ist es möglich. Also schneiden Sie Ihre Zehennägel mit einer laufenden Kettensäge. Weder sind sehr gute Ideen. – paxdiablo

Antwort

45

Nach Generate a Regular Expression to Match an Arbitrary Numeric Range, und nach einer solchen einen regulären Ausdruck für Ihr Beispiel bei Regex_For_Range zu erzeugen:

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b 

würde den Trick tun.

Der Prozess würde (noch folgenden daß Regex Generator):

zuerst, in gleicher Länge brechen Bereiche:

110 - 999 
1000 - 2234 

Zweitens brechen in Bereiche, die einfach Regexes Ausbeute :

110 - 199 
200 - 999 
1000 - 1999 
2000 - 2199 
2200 - 2229 
2230 - 2234 

Schalten jeden Bereich in einen regulären Ausdruck:

1[1-9][0-9] 
[2-9][0-9]{2} 
1[0-9]{3} 
2[01][0-9]{2} 
22[0-2][0-9] 
223[0-4] 

Collapse benachbarte Potenzen von 10: 1 [1-9] [0-9] [2-9] [0- 9] {2} 1 [0-9] {3} 2 [01] [0-9] {2} 22 [0-2] [0-9] 223 [0-4]

Die Kombination der obigen Regexe ergibt:

0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4]) 

Als nächstes werden wir versuchen, gemeinsame Präfixe Ausklammern einen Baum mit:
Parse in Baum basierend auf regex Präfixe:

. 1 [1-9] [0-9] 
+ [0-9]{3} 
+ [2-9] [0-9]{2} 
+ 2 [01] [0-9]{2} 
+ 2 [0-2] [0-9] 
+ 3 [0-4] 

Drehen des Parse-Baum in eine Regex-Erträge:

0*(1([1-9][0-9]|[0-9]{3})|[2-9][0-9]{2}|2([01][0-9]{2}|2([0-2][0-9]|3[0-4]))) 

Wir wählen den kürzeren als unser Ergebnis.

\b0*(1[1-9][0-9]|[2-9][0-9]{2}|1[0-9]{3}|2[01][0-9]{2}|22[0-2][0-9]|223[0-4])\b 
+0

A C#/VB.NET/PHP oder einer anderen Sprache außer der, die ich nicht weiß, wäre toll. ;) – Echilon

+14

+1 für beide beeindruckend und ein bisschen beängstigend. – joshin4colours

+0

Übrigens würde dies 000, 001, 010, etc. entsprechen. – insaner

17

Dies ist nicht die Art von Sache Regexes übertreffen. Sie werden es wahrscheinlich leichter finden, sicherzustellen, dass Sie die richtige Anzahl an Ziffern haben /^([0-9]{3,4})$/ und dann weitere Prüfungen gegen die Erfassung durchführen.

3

Es ist möglich, dass es nicht schön ist.

\b(?:[1][1][0-9]|1\d{3}|223[0-4]|2[0-1]\d\d|2[0-2][0-3][0-4])\b 

mailte ich Phillip Hazel, den Autor von PCRE, im Jahr 2006, was er in regex von Mathematik dachte:

Vielleicht liegt außerhalb des Umfangs des Projektes in Ihrer Sicht: Die Fähigkeit, Behandle Zahlen als Zahlen und nicht als Text, das wäre auf jeden Fall ein lohnendes Feature. Erlauben Sie Ihnen, einige grundlegende mathematische Prüfungen auf übereinstimmenden Ziffern zu machen, wie: ist die zweite übereinstimmende Ziffer höher oder niedriger, ist die dritte Ziffer ein Vielfaches von der ersten, und viele kompliziertere Fälle, die ich nicht näher ausführen werde, nur um meinen Punkt zu bekommen über. Fühlst du, dass dies den Bereich der Textanpassung übersteigt?

zu denen bekam ich folgende Antwort:

Ja, ich denke, ich tue, und auch, es ist nicht etwas, das in Perl regulären Ausdrücken zur Verfügung steht. Ich weiß, dass PCRE einige Erweiterungen von Perl hat, aber nichts als Haupt wie (Sie vielleicht etwas nach oben mit Legenden hacken könnten, aber das wäre ein bisschen ad hoc , und ohne Zweifel sehr chaotisch sein!).

Philip

und ich konnte nicht mehr zustimmen jetzt in `09. Passen Sie einfach alle Zahlen an und validieren Sie die Nummer in der Sprache, mit der Sie das Matching durchführen.

+0

Ich zögerte, die Schreibweise des Zitats zu korrigieren, aber ich möchte nicht, dass sich die falschen Buchstabiermeme verbreiten. – Svante

+0

Dies würde nicht mit den Zahlen im Bereich 120-199 – insaner

4

Während Sie es tun könnte mit etwas absurd suchen regex (als VonC beantwortet), regex wirklich soll dies nicht tun .. Warum nicht die Nummer verschieben auf die umgeleitet-to-Überprüfung Skript?

Wenn Nummern 110-2234 zu script1 gehen, und 1-109 gehen SCRIPT2, wäre es viel sein einfacher alle Nummern direkt an einem router Skript, und haben es an die richtige Stelle umleiten (via HTTP-Umleitungen) ..

In .htaccess:

RewriteRule ^view/([0-9]+)/?$ router.php?page=$1 [L] 

..dann in router.php, so etwas wie:

<?PHP 
if(
    int($_GET['page']) > 110 && 
    int($_GET['page']) < 2234 
){ 
    header("Status: 301 Moved Permanently\nLocation: /script1"); 
}else{ 
    header("Status: 404 Not Found"); 
} 
?> 
+0

Ich weiß das. Ich würde es gerne in .htaccess machen und vermeiden, PHP zu laden und einfach die richtige statische Datei zu laden :-) – barredo

+0

Aber danke für die Antwort !! :-) – barredo

3

können Sie die regulären Ausdrücke zusammen für folgende Bereiche gelegt:

1[1-9]\d = 110-199 
[2-9]\d\d = 200-999 
1\d\d\d = 1000-1999 
2[0-1]\d\d= 2000-2199 
22[0-2]\d = 2200-2229 
223[0-4] = 2230-2234 

zu bilden:

(1[1-9]\d|[2-9]\d\d|1\d\d\d|2[0-1]\d\d|22[0-2]\d|223[0-4]) 

\ d Mittel [0-9 ], aber in drei weniger Zeichen

Verwandte Themen