2012-09-05 31 views
8

Dấu ngoặc vuông đôi có nghĩa là gì trong một regex? Tôi đang bối rối về các ví dụ sau:Cách sử dụng dấu ngoặc kép trong cụm từ thông dụng?

/[[^abc]]/ 

/[^abc]/ 

tôi đã được thử nghiệm sử dụng Rubular, nhưng tôi không thấy bất kỳ sự khác biệt giữa một với dấu ngoặc kép và dấu ngoặc đơn.

+0

tôi đã tạo [mở rộng-ngoặc] (https://www.npmjs.com/package/ mở rộng dấu ngoặc đơn), nếu bạn quan tâm đến việc xem triển khai javascript phù hợp với các lớp nhân vật posix – jonschlinkert

Trả lời

8

Posix character classes sử dụng một ký hiệu [:alpha:], được sử dụng bên trong một biểu thức chính quy như:

/[[:alpha:][:digit:]]/ 

Bạn sẽ cần phải cuộn xuống một cách để có được thông tin Posix trong liên kết ở trên. Từ tài liệu:

Biểu thức khung POSIX cũng tương tự như các lớp ký tự. Chúng cung cấp một giải pháp thay thế di động ở trên, với lợi ích bổ sung mà chúng bao gồm các ký tự không phải ASCII. Ví dụ,/\ d/chỉ khớp các chữ số thập phân ASCII (0-9); trong khi/[[: chữ số:]]/khớp với bất kỳ ký tự nào trong thể loại Unicode Nd.

/[[:alnum:]]/ - Alphabetic and numeric character 
/[[:alpha:]]/ - Alphabetic character 
/[[:blank:]]/ - Space or tab 
/[[:cntrl:]]/ - Control character 
/[[:digit:]]/ - Digit 
/[[:graph:]]/ - Non-blank character (excludes spaces, control characters, and similar) 
/[[:lower:]]/ - Lowercase alphabetical character 
/[[:print:]]/ - Like [:graph:], but includes the space character 
/[[:punct:]]/ - Punctuation character 
/[[:space:]]/ - Whitespace character ([:blank:], newline, 
carriage return, etc.) 
/[[:upper:]]/ - Uppercase alphabetical 
/[[:xdigit:]]/ - Digit allowed in a hexadecimal number (i.e., 0-9a-fA-F) 

Ruby cũng hỗ trợ các phi POSIX lớp nhân vật sau đây:

/[[:word:]]/ - A character in one of the following Unicode general categories Letter, Mark, Number, Connector_Punctuation 
/[[:ascii:]]/ - A character in the ASCII character set 
# U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO" 

/[[:digit:]]/.match("\u06F2") #=> #<MatchData "\u{06F2}"> 
/[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He"> 
/[[:xdigit:]][[:xdigit:]]/.match("A6") #=> #<MatchData "A6"> 
+0

Câu trả lời này đã được thêm vào [FAQ Overflow Regular Expression FAQ] (http://stackoverflow.com/a/22944075/2736496), trong "Class Character". – aliteralmind

4

'[[' không có bất kỳ ý nghĩa đặc biệt nào. [xyz] là một lớp nhân vật và sẽ khớp với một đơn x, y hoặc z. Carat ^ lấy tất cả ký tự không nằm trong dấu ngoặc vuông.

Xóa ^ để đơn giản, bạn có thể thấy rằng khung mở đầu tiên được khớp với dấu đóng đầu tiên và khung đóng thứ hai đang được sử dụng như một phần của lớp ký tự. Khung đóng cuối cùng được coi là một ký tự khác cần khớp.

irb(main):032:0> /[[abc]]/ =~ "[a]" 
=> 1 
irb(main):033:0> /[[abc]]/ =~ "a]" 
=> 0 

này dường như có cùng một kết quả như ban đầu của bạn trong một số trường hợp

irb(main):034:0> /[abc]/ =~ "a]" 
=> 0 
irb(main):034:0> /[abc]/ =~ "a" 
=> 0 

Nhưng đây chỉ là vì biểu hiện thường xuyên của bạn không tìm kiếm một kết hợp chính xác.

irb(main):036:0> /^[abc]$/ =~ "a]" 
=> nil 
+1

Hãy lưu ý rằng điều này không đúng với tất cả các hương vị regex. Ví dụ, Java sẽ coi nó như là một lớp nhân vật không chứa gì ngoài một lớp ký tự khác, vì vậy '[[^ abc]]' và '[^ abc]' có hiệu quả giống hệt nhau. –

+0

FWIW - Python có hành vi tương đương với câu trả lời ở trên, không chắc chắn về các ngôn ngữ khác, hoặc những gì nó 'nên' đang làm, mặc dù tôi thích hành vi @AlanMoore đề cập đến. – dfb

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