2009-03-24 15 views
22

Tôi muốn khớp với RegExp một số giữa X và Y. Điều đó có khả thi không?Làm cách nào để khớp số giữa X và Y với regexp?

([0-9] +) sẽ khớp với bất kỳ số nào, làm cách nào tôi có thể thực hiện để khớp một số giữa, ví dụ: 110 và 2234?

+25

Có thể thực hiện được. Vì vậy, là cắt móng chân của bạn với một cưa chạy. Cả hai đều là những ý tưởng rất hay. – paxdiablo

Trả lời

45

Theo Generate a Regular Expression to Match an Arbitrary Numeric Range, và sau khi tạo ra như một regex ví dụ của bạn tại 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 

sẽ làm các trick.

Quá trình này sẽ được (vẫn còn sau đó Regex máy phát điện):

Thứ nhất, đột nhập vào chiều dài bằng nhau dao động:

110 - 999 
1000 - 2234 

Thứ hai, đột nhập vào dãy số mang regexes đơn giản :

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

Bật mỗi phạm vi thành một 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 quyền hạn liền kề 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]

Kết hợp các regex ở trên sản lượng:

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

Tiếp theo chúng ta sẽ cố gắng thanh toán ra tiền tố phổ biến sử dụng một cây:
Parse vào cây dựa trên tiền tố regex:

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

Biến cây phân tích cú pháp thành một regex yields:

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

Chúng tôi chọn kết quả ngắn hơn là kết quả của chúng tôi.

\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 hoặc bất kỳ ngôn ngữ nào khác ngoại trừ ngôn ngữ tôi không biết sẽ là tuyệt vời. ;) – Echilon

+14

+1 cho cả một ấn tượng và một chút đáng sợ. – joshin4colours

+0

bằng cách này, điều này sẽ phù hợp với 000, 001, 010, v.v. – insaner

17

Đây không phải là loại điều regexes nổi trội tại. Bạn có thể sẽ thấy dễ dàng hơn để đảm bảo rằng bạn có đúng số chữ số /^([0-9]{3,4})$/ và sau đó thực hiện kiểm tra thêm đối với việc chụp.

3

Có thể mặc dù không đẹp.

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

tôi gửi qua email Phillip Hazel, tác giả của PCRE, năm 2006 những gì anh nghĩ về toán học trong regex:

Có lẽ điều này nằm ngoài phạm vi của dự án theo quan điểm của bạn: Khả năng đối xử với con số như số lượng và không phải là văn bản, điều này chắc chắn sẽ là một tính năng đáng giá. Cho phép bạn thực hiện một số phép tính toán cơ bản trên các chữ số phù hợp, như: là chữ số thứ 2 cao hơn hoặc thấp hơn, là chữ số thứ ba đa số thứ nhất và nhiều trường hợp phức tạp hơn. . Bạn có cảm thấy điều này vượt quá phạm vi của textmatching không?

mà tôi nhận được câu trả lời sau đây:

Vâng, tôi nghĩ rằng tôi làm, và cũng có thể, nó không phải là cái gì đó có sẵn trong Perl biểu thức thông thường. Tôi biết rằng PCRE không có một số tiện ích mở rộng từ Perl, nhưng không có gì lớn như vậy (bạn có thể có thể hack một số nội dung bằng cách sử dụng chú thích , nhưng đó sẽ là một quảng cáo bit và không nghi ngờ gì nhiều!).

Philip

và tôi không thể đồng ý bây giờ nhiều hơn trong `09. Chỉ cần khớp tất cả các số và thực hiện xác thực số bằng bất kỳ ngôn ngữ nào bạn đang thực hiện khớp với.

+0

Tôi đã miễn cưỡng sửa lỗi chính tả của báo giá, nhưng tôi không muốn các bản ghi sai chính tả lan truyền. – Svante

+0

Điều này sẽ không khớp với các số trong khoảng 120-199 – insaner

4

Trong khi bạn có thể làm điều đó với một số tìm kiếm regex ngớ ngẩn (như VonC trả lời), regex thực sự là không được phép làm điều này .. Tại sao không trì hoãn số kiểm tra để các chuyển hướng-to- kịch bản?

Nếu số 110-2234 đi đến script1, và 1-109 đi đến script2, nó sẽ là nhiều đơn giản chỉ đạo tất cả các số tại một kịch bản router, và có nó chuyển hướng đến đúng vị trí (thông qua HTTP chuyển hướng) ..

Trong .htaccess:

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

..sau đó trong router.php, một cái gì đó như:

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

Tôi biết điều đó. Tôi muốn làm cho nó trong .htaccess và tránh tải php và chỉ cần tải các tập tin tĩnh phải :-) – barredo

+0

Nhưng cảm ơn cho câu trả lời !! :-) – barredo

3

Bạn có thể đặt các regexes cho các phạm vi sau đây với nhau:

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 

mẫu:

(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 phương tiện [0-9 ], nhưng trong ba ký tự ít hơn

Các vấn đề liên quan