2010-07-19 29 views
7

Tôi cần phải khớp 8 chữ số trở lên, trình tự có thể bao gồm dấu cách. Ví dụ:Bỏ qua không gian màu trắng cho một trận đấu Regex

ví dụ, tất cả các bên dưới sẽ là kết quả phù hợp hợp lệ.

12345678 
1 2345678 
12 3 45678 
1234 5678 
12 34567 8 
1 2 3 4 5 6 7 8 

Hiện tại tôi có \d{8,} nhưng điều này sẽ chỉ chụp một khối chắc chắn từ 8 chữ số trở lên.
[\d\s]{8,} sẽ không hoạt động vì tôi không muốn không gian trắng đóng góp vào số lượng ký tự được ghi lại.

Trả lời

1

Waayy sau đó, nhưng điều này thực sự cần câu trả lời đúng trên đó và lý do tại sao. Ai biết câu hỏi này có thể có một câu trả lời phức tạp như vậy, đúng không? Lol. Nhưng có rất nhiều cân nhắc xung quanh khoảng cách trong regex.

Thứ nhất; Không bao giờ đặt một không gian trong một regex. Làm như vậy sẽ làm cho regex của bạn không thể đọc được và không thể thực hiện được. Những kỷ niệm sử dụng chuột để làm nổi bật một không gian để đảm bảo nó chỉ là một không gian xuất hiện trong tâm trí bạn. Điều này sẽ phá vỡ regex của bạn:    , nhưng điều này sẽ không: [   ], vì việc lặp lại trong một lớp nhân vật bị bỏ qua. Và nếu bạn yêu cầu số lượng không gian chính xác, bạn thực sự có thể thấy rằng trong một lớp nhân vật như vậy: [ ]{3}. So với tai nạn mà không có lớp nhân vật như vậy:     {3} < - Điều này thực sự đang tìm kiếm 5 không gian, các vòng lặp!

Thứ hai; Giữ tùy chọn Freespacing (?x) trong tâm trí, điều này làm cho regex của bạn có thể nhận xét và không thể truy cập được. Bạn không nên sợ rằng ai đó sử dụng tùy chọn đó có thể phá vỡ regex của bạn bởi vì bạn quyết định đặt không gian bàn phím ngẫu nhiên trong đó. Ngoài ra, (?x) sẽ không bỏ qua không gian bàn phím khi nằm trong lớp ký tự như vậy: [ ]. Do đó, an toàn hơn khi sử dụng các lớp ký tự cho không gian bàn phím của bạn.

Thứ ba; Cố gắng không sử dụng \s trong trường hợp này. Như Omaghosh chỉ ra, nó cũng bao gồm các dòng mới (\r\n). Kịch bản bạn đã đề cập dường như không có lợi cho điều đó. Tuy nhiên, cũng như Omaghosh chỉ ra, bạn có thể muốn nhiều hơn chỉ là không gian bàn phím. Vì vậy, bạn có thể sử dụng [ ], [\s-[\r\n]] hoặc [\f\t\v\u00A0\u2028\u2029\u0020] tùy thuộc vào những gì bạn ưa thích. Hai cái cuối cùng trong các tùy chọn này là giống nhau, nhưng phép trừ lớp ký tự chỉ hoạt động trong .NET và một vài mùi lạ khác.

Thứ tư; Đây là mẫu thường được xây dựng quá mức: (\s*...\s*)*.Nó không có ý nghĩa gì cả. Nó giống như sau: (\s*\s*...)* hoặc điều này: (\s*\s*\s*\s*...)*. Bởi vì mô hình lặp lại. Lý lẽ duy nhất chống lại những gì tôi nói là bạn sẽ được đảm bảo nắm bắt các khoảng trống trước .... Nhưng không một lần nào là điều thực sự muốn. kịch bản trường hợp xấu nhất, bạn có thể thấy điều này: \s*(...\s*)*

Omaghosh có câu trả lời gần nhất, nhưng đây là câu trả lời đúng ngắn nhất:

Regex.Match(input, @"(?:\d[ ]*){8,}").Groups[0].Value; 

Hoặc sau đây, nếu chúng ta lấy câu hỏi theo nghĩa đen mà sáu tùy chọn đang ở trong cùng một văn bản trên nhiều dòng:

Regex.Match(input, @"(?m)^(?:\d[ ]*){8,}$").Groups[0].Value; 

Hoặc sau đây, nếu nó là một phần của một regex lớn hơn và cần một nhóm:

Regex.Match(input, @"...((?:\d[ ]*){8,})...").Groups[1].Value; 

Và cảm thấy tự do để thay thế [ ] với .NET Lớp Trừ, hoặc một Non-.NET rõ ràng lớp khoảng trắng:

@"(?:\d[\s-[\r\n]]*){8,}" 
// Or . . . 
@"(?:\d[\f\t\v\u00A0\u2028\u2029\u0020]*){8,}" 
+0

Câu trả lời tuyệt vời! –

0
(\d{8,}\s+)*\d{8,} 

nên làm việc

+0

kiểm tra này trong Expressio, nó chỉ phù hợp '12345678' và không ai trong số các khác ví dụ. –

+0

@Greg B: Tôi hiểu ý của bạn là gì. Tôi đã không chắc chắn. Thành thật mà nói, tôi không nghĩ rằng nó có thể trong regex 'vanilla', nhưng tôi chắc chắn có một thủ thuật để xử lý nó. Một tùy chọn khác là xóa tất cả khoảng trắng trước khi áp dụng Regex. – leppie

13
(\d *){8,} 

Nó phù hợp với tám hoặc nhiều lần xuất hiện của một chữ số tiếp theo không hay nhiều không gian. Thay đổi nó thành

(*\d *){8,} #there is a space before first asterik 

để khớp các chuỗi với dấu cách ở đầu. Hoặc

(\s*\d\s*){8,} 

để khớp các tab và các ký tự khoảng trắng khác (bao gồm cả dòng mới).

Cuối cùng, biến nó thành nhóm không chụp với ?:. Do đó, nó sẽ trở thành (?:\s*\d\s*){8,}

+0

+1: Không tệ :) (văn bản phụ) – leppie

+1

+1 '\ s * \ d \ s * {8,}' thực sự là '(\ s * \ d \ s *) {8,}' – TheVillageIdiot

+0

@ TheVillateIdiot Đã sửa lỗi rồi :) – Amarghosh

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