2011-08-19 33 views
8

Tôi đã xem qua biểu thức chính quy này trong mã nguồn jQuery:Phần biểu thức chính quy này thêm gì?

... 
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, 
... 

tôi đã tự hỏi tại sao nó lại khá phức tạp. Tôi đặc biệt quan tâm đến lý do đằng sau phần thứ hai:

(?:.*? rv:([\w.]+))? 

tôi đã làm một số nghiên cứu nhưng tôi không thể tìm ra những gì phần này của biểu thức chính quy cho biết thêm.

(?:)  to match but not capture 
.*?  any amount of any character 
rv:  something literal 
([\w.]+) one or more word characters or a dot 
?   appear 0 or 1 time 

Đặc biệt, điều đó cuối cùng ? không có ý nghĩa nhiều với tôi. Toàn bộ phần thứ hai phù hợp nếu có hoặc không phải là một chuỗi con như được xác định bởi phần thứ hai đó. Với một số thử nghiệm và sai sót, cụm từ thông dụng dường như không khác với chỉ:

/(mozilla)/ 

Ai đó có thể làm sáng tỏ phần thứ hai của cụm từ thông dụng phải làm gì? Nó hạn chế điều gì; chuỗi nào bị lỗi khi vượt qua /(mozilla)/ hoặc vòng khác?

+0

tôi nghi ngờ nó để làm việc xung quanh một số trình duyệt Mozilla giả mạo bằng cách đặt nó trong chuỗi user-agent của họ. –

+0

Bạn có thể cung cấp thêm một chút ngữ cảnh không? Đây có phải là một phần của một plugin jQuery không? Nếu vậy thì cái nào? Biết nơi mã này xuất hiện có thể làm sáng tỏ một số/lý do/tác giả muốn mẫu đặc biệt này, và do đó mô hình đang làm. – jefflunt

+0

@Rafe Kettler: Tôi không chắc tôi hiểu chính xác bạn. Regexp thêm gì để ngăn chặn kẻ thù? – pimvdb

Trả lời

4

Hai regex sẽ khớp với cùng một chuỗi, nhưng sẽ lưu trữ thông tin khác nhau trong nhóm chụp của chúng.

cho chuỗi: mozilla asdf rv:sadf

/(mozilla)(?:.*? rv:([\w.]+))?/ 
$0 = 'mozilla asdf rv:sadf' 
$1 = 'mozilla' 
$2 = 'sadf' 

/(mozilla)/ 
$0 = 'mozilla' 
$1 = 'mozilla' 
$2 = '' 
1

([\w.]+) bên trong (?:.*? rv:([\w.]+)) đang chụp, vì vậy có thể regex này đã được sử dụng để nhận số sửa đổi trong quá khứ (tuy nhiên có vẻ như jquery hiện chỉ kiểm tra xem regex có khớp) không.

2

Trước tiên, tôi muốn làm rõ sự khác biệt giữa:

.*? - non-greedy match 
.* - greedy match 

Các phi tham lam sẽ phù hợp với số lượng nhỏ nhất của byte có thể (cho phần còn lại của chuỗi tìm kiếm), và một trong những tham lam sẽ phù hợp nhất.

Với chuỗi:

mozilla some text here rv:abc xyz 

Các regex sẽ trả lại cả hai 'mozilla' và 'abc'. Nhưng nếu 'rv:' không tồn tại, regex sẽ vẫn trả về 'mozilla'.

+0

Đúng, nhưng chúng thường được gọi là "không tham lam" và "tham lam", tương ứng. –

+0

Có. Ký ức của tôi hơi buồn cười theo cách đó. Tôi sẽ chỉnh sửa. –

0

(pat) là một dấu phân cách khuôn mẫu cho phù hợp với một mô hình chứa đầy đủ. (?: Pat) là phủ định ở trên, giống như khung Đặt ký tự [^] là phủ định của []. Trong javascript, phủ định xảy ra với ! . khớp với bất kỳ ký tự nào, * là một định lượng của các kết quả phù hợp và có thể trong các Công cụ Regex mới hơn cũng được viết là {0,} (nhưng ba ký tự bổ sung đó có thể dẫn đến cái chết trước đó của bàn phím!) ? định lượng đối sánh dư thừa: có thể khớp với 0 hoặc rv: .... literal rv

một đối số con khác, có thể không khớp hoặc một lần trong kết nối gốc ([\ w.] +))? [\ w.] ...bộ ký tự, với ký tự w "\ w": bất kỳ ký tự chữ và số nào, hay còn gọi là [a-zA-Z0-9_], sau đó là dấu chấm đen và mỗi số lượng đối sánh +, có thể xuất hiện một hoặc nhiều lần

ý nghĩa của kết hợp mẫu: chỉ cần đánh giá từ trái sang phải, trong trình soạn thảo văn bản và thay thế các chữ cái bằng các chữ cái ngẫu nhiên đến tâm trí và mỗi biểu thức phụ phù hợp. Sau đó, hãy lùi lại một bước và suy nghĩ xem regex có thể là gì.

+1

Hãy tận dụng tính năng [định dạng mã] của SO (http://stackoverflow.com/editing-help#code); như bây giờ, câu trả lời của bạn gần như không đọc được. –

+1

Câu trả lời cũng chứa một số lỗi, để wit: ** 1. ** '(pat)' là một nhóm chụp; ** 2. ** '(?: Pat)' là một nhóm * không chụp *, không phải là một cái nhìn tiêu cực như bạn dường như ngụ ý (đó sẽ là '(?! Pat)'); ** 3. ** '*' tương đương với '{0,}' trong hầu như tất cả các hương vị regex - tuổi tác không liên quan gì đến nó; ** 4. ** rằng '?' Đầu tiên làm cho '*' không thích hợp trước (không thừa); ** 5. ** '[\ w.]' Tương đương với '[A-Za-z0-9 _.]' (Tức là, nó khớp với một ký tự từ * hoặc dấu chấm *, chứ không phải * theo sau là dấu chấm *, như bạn đã nói. –

2

Lưu ý: Tôi bây giờ nhận thấy rằng câu trả lời này có thể nằm ngoài phạm vi. Tôi vẫn sẽ để lại nó để biết thêm thông tin, nhưng nếu bạn nghĩ rằng nó là quá nhiều ra khỏi phạm vi, chỉ cần bình luận và tôi sẽ loại bỏ nó.


@arnaud đúng, để lấy phiên bản. Here is the code nơi các biểu thức được sử dụng:

uaMatch: function(ua) { 
    ua = ua.toLowerCase(); 

    var match = rwebkit.exec(ua) || 
       ropera.exec(ua) || 
       rmsie.exec(ua) || 
       ua.indexOf("compatible") < 0 && rmozilla.exec(ua) || 
       []; 

    return { browser: match[1] || "", version: match[2] || "0" }; 
}, 

Bạn có thể thấy rằng hàm trả về phiên bản nếu tìm thấy và 0 nếu không muốn nói. Điều này có thể cần thiết đối với một số trình duyệt hoặc chỉ được cung cấp dưới dạng thông tin bổ sung cho nhà phát triển.

Các hàm được gọi here:

browserMatch = jQuery.uaMatch(userAgent); 
if (browserMatch.browser) { 
    jQuery.browser[ browserMatch.browser ] = true; 
    jQuery.browser.version = browserMatch.version; 
} 
Các vấn đề liên quan