2009-03-24 11 views

Odpowiedz

45

Według Generate a Regular Expression to Match an Arbitrary Numeric Range, a po wygenerowaniu takiego regex dla przykładu w Regex_For_Range:

\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 

by rade.

Proces będzie (jeszcze po Regex generatora)

pierwsze, podzielić na równe długości wynosi:

110 - 999 
1000 - 2234 

drugie, podzielić na grupy, które dają proste regexes :

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

Włącz każdy zakres w regex:

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 sąsiednie uprawnień 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]

Łączenie wyrażeń regularnych powyżej wydajności:

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

Następny postaramy faktoringu wspólne przedrostki użyciem drzewa:
Parse do drzewa w oparciu o regex prefiksów:

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

Włączanie drzewo składniowy w Wydajność zwrotna:

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

Wybieramy krótszy jako nasz wynik.

\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

C#/VB.NET/PHP lub w jakimkolwiek innym języku poza tym, którego nie znam, byłoby świetne. ;) – Echilon

+14

+1 za imponujące i trochę przerażające. – joshin4colours

+0

przy okazji, to pasowałoby do 000, 001, 010, itd. – insaner

17

To nie jest coś takiego Wyrażenia regularne celują. Prawdopodobnie łatwiej będzie Ci zapewnić, że masz odpowiednią liczbę cyfr /^([0-9]{3,4})$/, a następnie wykonaj dalsze kontrole przeciwko przechwytywaniu.

3

Możliwe allbeit nie całkiem.

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

wysłałem maila Phillip Hazel, autor PCRE, w 2006 roku, co sądzi o matematyka jest w regex:

Może to leży poza zakresem projektu w widoku: zdolność do traktuj liczby jako liczby, a nie tekst, to z pewnością warto byłoby. Pozwalając, aby zrobić kilka podstawowych kontrole matematycznych na dopasowanych cyfr, jak: jest 2. dopasowane cyfra większa lub mniejsza, to trzecia cyfra wielokrotnością off 1, a wiele bardziej skomplikowane przypadki, ja nie będę się rozpisywał na tylko dostać mój punkt widzenia accross. Czy uważasz, że wykracza to poza obszar tekstowy?

do którego dostałem następującą odpowiedź:

Tak, myślę, że to zrobię, a także, że nie jest coś, co jest dostępne w Perl wyrażeń regularnych. Wiem, że PCRE ma kilka rozszerzeń z Perla, , ale nic tak dużego jak to (Ty może coś zhakować używając objaśnień , ale to byłoby trochę ad hoc, i bez wątpienia niezmiernie brudny!).

Philip

i nie mogłem zgodzić się obecnie w `09. Po prostu dopasuj wszystkie liczby i sprawdź poprawność numerów w języku, w którym robisz dopasowywanie.

+0

Nie chciałem poprawiać pisowni cytatu, ale nie chcę, aby niepoprawne meme ortograficzne się rozprzestrzeniały. – Svante

+0

To nie pasuje do liczb w zakresie 120-199 – insaner

4

Podczas mógłby zrobić z jakiegoś absurdalnego poszukuje regex (jak odpowiedział VonC) regex naprawdę nie ma to zrobić .. Dlaczego nie odroczyć liczby kontroli do przekierowanego-to- scenariusz?

Jeśli numery 110-2234 iść do script1 i 1-109 iść do script2 byłoby znacznie prostsze skierować wszystkie numery w router skryptu i go przekierować do właściwej lokalizacji (poprzez przekierowań HTTP) ..

W .htaccess:

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

..następnie w router.php, coś jak:

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

Wiem o tym. Chciałbym zrobić to w .htaccess i uniknąć ładowania php i po prostu załadować odpowiedni plik statyczny :-) – barredo

+0

Ale dzięki za odpowiedź !! :-) – barredo

3

można umieścić regexes dla następujących zakresów razem:

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 

do postaci:

(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 oznacza [0-9 ], ale w trzech mniej znaków

Powiązane problemy