2015-06-09 19 views
7

Tôi có regex này:regex hiệu quả nhất để kiểm tra xem một chuỗi có chứa ít nhất 3 ký tự chữ và

(?:.*[a-zA-Z0-9].*){3} 

tôi sử dụng nó để xem nếu một chuỗi có ít nhất 3 ký tự chữ và số trong đó. Dường như nó hoạt động.

Ví dụ về chuỗi nó phải phù hợp:

'a3c' 
'_0_c_8_' 
' 9 9d ' 

Tuy nhiên, tôi cần nó để làm việc nhanh hơn. Có cách nào tốt hơn để sử dụng regex để phù hợp với các mẫu giống nhau không?


Edit: tôi đã kết thúc bằng regex này cho các mục đích của tôi:

(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3} 

(không bổ cần thiết)

+0

Bạn quan tâm đến hương vị regex nào? –

+0

@stribizhev Tôi quan tâm đến ECMAScript regex – fizix00

Trả lời

6

Phương pháp regex hiệu quả nhất là sử dụng principle of contrast, ví dụ: sử dụng ngược lại các lớp nhân vật cạnh nhau.Dưới đây là một regex mà có thể được sử dụng để kiểm tra xem một chuỗi có 3 chữ cái kịch bản Latinh hoặc chữ số:

^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3} 

See demo.

Trong trường hợp bạn cần kết hợp chuỗi đầy đủ, bạn sẽ cần phải thêm .* (hoặc .*$ nếu bạn muốn đảm bảo bạn sẽ khớp với hết chuỗi/dòng), nhưng trong bài kiểm tra của tôi trên regexhero, .* sản lượng hiệu suất tốt hơn):

^(?:[^a-zA-Z0-9]*[a-zA-Z0-9]){3}.* 

Ngoài ra, rất nhiều phụ thuộc vào động cơ. PCRE có tối ưu hóa tự động tại chỗ bao gồm trong tự động sở hữu (tức là nó biến * thành *+ trong (?:[^a-zA-Z0-9]*+).

Xem more details on password validation optimizations đây.

+2

regex có thể được neo, và '. * 'đã xóa. – nhahtdh

+0

Tôi đã kiểm tra nhiều thứ, và nó chỉ ra rằng '(?: [^ A-zA-Z0-9] * [a-zA-Z0-9]) {3}. *' Thực sự chậm hơn '^ (?: [^ a-zA-Z0-9] * [a-zA-Z0-9]) {3} '(~ 17%). Tôi đã chỉnh sửa câu trả lời. Tôi tin rằng sự bắt đầu của chuỗi neo thực sự hữu ích ở đây, tôi đã thử nghiệm dựa vào đầu vào được cung cấp trên regexhero và '(?: [^ A-zA-Z0-9] * [a-zA-Z0-9]) { 3}. * 'Mẫu mang lại 422,318 lần lặp/giây,' (?: [^ A-zA-Z0-9] * [a-zA-Z0-9]) {3} '(không có'. * ') Mang lại 341,375 ips, và '^ (?: [^ A-zA-Z0-9] * [a-zA-Z0-9]) {3}' mang lại ... 1,371,000 ips :) –

+1

Nếu không có thử nghiệm, thật dễ dàng để xem '. *' sẽ bằng hoặc chậm hơn (thường chậm hơn, vì động cơ cần kiểm tra xem phần còn lại của chuỗi có ký tự dòng mới hay không, mặc dù nó có thể bỏ qua ở chế độ 's'). '^' Sẽ buộc trận đấu chỉ được thực hiện ở đầu chuỗi, do đó, tất nhiên, nó tránh tìm kiếm từ các chỉ mục tiếp theo khi không có kết quả nào từ chỉ mục 0. – nhahtdh

3
(?:.*?[a-zA-Z0-9]){3}.* 

Bạn có thể sử dụng this.This là nhanh hơn nhiều và mất bước nhỏ hơn nhiều so với yours.See demo.You có lẽ sẽ muốn sử dụng ^$ neo quá chắc chắn đó không ứng với một phần.

https://regex101.com/r/nS2lT4/32

Lý do là

(?:.*[a-zA-Z0-9].*){3} 

       ^^ 

Điều này thực sự tiêu thụ toàn bộ chuỗi và sau đó động cơ phải backtrack.When sử dụng regex khác này là tránh

+0

nếu nó ok để phù hợp với gạch cũng có, thay charset với \ w cũng cải thiện một chút hiệu suất –

+0

@ RodrigoLópez m không phải là rất chắc chắn OP muốn điều đó :( – vks

+1

Ừ, có lẽ không –

2

Chỉ cần xem xét việc này. biểu thức thông thường là mạnh mẽ bởi vì họ đang biểu cảm và rất linh hoạt (với các tính năng như nhìn về phía trước, tiêu thụ tham lam và back-theo dõi). Có gần như luôn sẽ là một chi phí vào đó, tuy nhiên nhỏ.

Nếu bạn muốn tốc độ thô (và bạn sẵn sàng từ bỏ tính biểu cảm), bạn có thể thấy rằng nhanh hơn bỏ qua cụm từ thông dụng và chỉ đánh giá chuỗi, chẳng hạn như với mã giả sau:

def hasThreeAlphaNums(str): 
    alphanums = 0 
    for pos = 0 to len(str) - 1: 
     if str[pos] in set "[a-zA-Z0-9]": 
      alphanums++ 
      if alphanums == 3: 
       return true 
    return false 

đó là một phân tích cú pháp (một rất đơn giản trong trường hợp này), một công cụ mà có thể còn hơn mạnh mẽ hơn biểu thức thông thường. Đối với một ví dụ cụ thể hơn, hãy xem xét mã C sau:

#include <ctype.h> 
int hasThreeAlphaNums (char *str) { 
    int count = 0; 
    for (int ch = *str; ch != '\0'; str++) 
     if (isalnum (ch)) 
      if (++count == 3) 
       return 1; 
    return 0; 
} 

Bây giờ, khi hay không đó là nhanh hơn cho trường hợp cụ thể này, điều đó phụ thuộc vào nhiều yếu tố, chẳng hạn như liệu ngôn ngữ được giải thích hoặc biên soạn, làm thế nào hiệu quả các regex là dưới bao gồm, và như vậy.

Đó là lý do tại sao thần chú của tối ưu hóa là "Measure, đừng đoán!" Bạn nên đánh giá các khả năng trong môi trường mục tiêu của bạn.

+0

tôi didn 't chọn này là câu trả lời vì nó không trả lời câu hỏi của tôi. Tuy nhiên, tôi nghĩ rằng đó là lời khuyên tốt, do đó, nhờ và +1. – fizix00

+1

@ user3772517, đó là okay, đôi khi tốt để xem xét các giải pháp _other_ vượt quá giới hạn áp đặt bởi các câu hỏi, vì người hỏi không luôn luôn có được quyền đó.Nhưng, nếu bạn cần một regex, sau đó bạn cần một regex, không có xung quanh đó :-) – paxdiablo

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