2012-10-08 33 views
20

Tôi muốn một regex có ký tự X hoặc Y dài. Ví dụ: khớp một chuỗi dài 8 hoặc 11 ký tự. Tôi hiện đã triển khai thực hiện điều này như sau: ^([0-9]{8}|[0-9]{11})$.Độ dài phù hợp cụ thể x hoặc y

tôi cũng có thể thực hiện nó như: ^[0-9]{8}([0-9]{3})?$

Câu hỏi của tôi là: Tôi có thể có regex này mà không cần sao chép các [0-9] phần (đó là phức tạp hơn \d ví dụ đơn giản này)?

Trả lời

31

Có một cách:

^(?=[0-9]*$)(?:.{8}|.{11})$ 

hoặc cách khác, nếu bạn muốn làm việc kiểm tra chiều dài đầu tiên,

^(?=(?:.{8}|.{11})$)[0-9]*$ 

Bằng cách đó, bạn chỉ có một phần phức tạp một lần và một số chung là . để kiểm tra độ dài.

Giải thích:

^  # Start of string 
(?=  # Assert that the following regex can be matched here: 
[0-9]* # any number of digits (and nothing but digits) 
$  # until end of string 
)  # (End of lookahead) 
(?:  # Match either 
.{8} # 8 characters 
|  # or 
.{11} # 11 characters 
)  # (End of alternation) 
$  # End of string 
+0

Rất đẹp ... Tôi sẽ phải tìm hiểu thêm về những cái nhìn này :) – Laoujin

+1

Hãy coi chừng: Nếu bạn lấy '^ (? = [0-9] * $) (?:. {8} |. {11}) $ 'phiên bản, nó có thể là lỗi cho IE5-8 như được giải thích [ở đây] (http://blog.stevenlevithan.com/archives/regex-lookahead-bug). Chuyển sang phiên bản thay thế của Tim và phiên bản này hoạt động với tất cả các trình duyệt. – Laoujin

+0

Lưu ý rằng cả hai phiên bản đều không được lược đồ XML hỗ trợ do nhóm không bắt (? :). – user1056903

1

Với Perl, bạn có thể làm:

my $re = qr/here_is_your_regex_part/; 
my $full_regex = qr/$re{8}(?:$re{3})?$/ 
+1

Đóng, nhưng đã bỏ lỡ một} sau '$ re {3' – mrk

+0

@mrk: Tốt, cảm ơn bạn. – Toto

0

Đối với những người trong chúng ta tìm kiếm để nắm bắt độ dài khác nhau của cùng nhiều thử này.

^(?:[0-9]{32})+$

đâu 32 là nhiều bạn muốn nắm bắt tất cả độ dài cho (32, 64, 96, ...).

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