Sự khác biệt giữa '.' , '?' và '*' trong biểu thức chính quy?


21

Tôi có thể lấy một ví dụ về việc ba yếu tố này (được gọi là siêu nhân vật không?) Khác nhau như thế nào?

Tôi biết điều đó *có nghĩa là tất cả hoặc không có gì, nhưng tôi không chắc liệu đó có phải là cách đúng đắn để nghĩ về nó hay không. Mặt khác .?có vẻ như vậy. Họ phù hợp với một nhân vật, phải không?



@Cyrus hoặc thậm chí tốt hơn: Tài liệu Regex StackOverflow .
Thomas Ayoub

Câu trả lời:


16

Lấy thẳng từ Wikipedia :

? Dấu hỏi chỉ ra không hoặc một lần xuất hiện của phần tử trước. Ví dụ: colou? R khớp với cả "màu" và "màu".

*Dấu hoa thị cho thấy không hoặc nhiều lần xuất hiện của phần tử trước. Ví dụ: ab * c khớp với "ac", "abc", "abbc", "abbbc", v.v.

Sự khác biệt lớn là các dấu hoa thị 0 hoặc nhiều lần xuất hiện, trong khi dấu hỏi khớp với 0 hoặc một lần xuất hiện. So sánh hai ví dụ sau:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Bởi vì trong colouurchữ u (phần tử trước trước vòng loại ?) đã xảy ra nhiều lần, nó không khớp với ?, nhưng nó được khớp với*

Ví dụ tương tự:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

Từ cùng một trang wikipedia:

Khớp với bất kỳ ký tự đơn nào (nhiều ứng dụng loại trừ dòng mới và chính xác các ký tự được coi là dòng mới là hương vị, mã hóa ký tự- và đặc thù nền tảng, nhưng có thể giả định rằng bao gồm ký tự nguồn cấp dữ liệu). Trong biểu thức khung POSIX, ký tự dấu chấm khớp với dấu chấm. Ví dụ: ac khớp với "abc", v.v., nhưng [ac] chỉ khớp với "a", "." Hoặc "c".

Trong ví dụ của chúng tôi,

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

Một cách thích hợp, người cuối cùng đọc là match any line that has "colou", plus any character, plus letter "r"

Phần kết luận

Bạn đã hỏi: "Tôi biết rằng '*' có nghĩa là tất cả hoặc không có gì, nhưng tôi không chắc liệu đó có phải là cách suy nghĩ đúng đắn hay không. Mặt khác '.' & '?' có vẻ giống nhau. " Như bạn có thể thấy, dấu chấm và dấu hoa thị không hoàn toàn giống nhau. Dấu chấm hoạt động trên bất kỳ ký tự nào có thể chiếm vị trí cụ thể đó, trong khi dấu hỏi hoạt động trên phần tử trước.


32

Bạn có thể nhầm lẫn giữa các biểu thức thông thường với vỏ

Trong cú pháp biểu thức chính quy .đại diện cho bất kỳ ký tự đơn nào (thường loại trừ ký tự dòng mới), trong khi đó *là một bộ định lượng có nghĩa là 0 hoặc nhiều hơn nguyên tử regex trước đó (ký tự hoặc nhóm). ?là một bộ định lượng có nghĩa là 0 hoặc một thể hiện của nguyên tử trước hoặc (trong các biến thể regex hỗ trợ nó) một công cụ sửa đổi đặt hành vi của bộ lượng hóa thành không tham lam.

Trong các khối vỏ, ?đại diện cho một ký tự (như regex .) trong khi *đại diện cho một chuỗi gồm 0 hoặc nhiều ký tự (tương đương với regex .*).

Một vài tài liệu tham khảo mà bạn có thể thấy hữu ích là http://www.THER-expressions.info/quickstart.htmlhttp://mywiki.wooledge.org/glob


6

Lưu ý: Examples provided are in Python.Mặc dù khái niệm vẫn giữ nguyên.

'.'là một biểu tượng phù hợp khớp với bất kỳ ký tự nào ngoại trừ ký tự dòng mới (điều này cũng có thể được ghi đè bằng re.DOTALLđối số trong Python). Do đó, nó cũng được gọi là Wildcard .

'*'là một bộ định lượng (xác định tần suất một phần tử có thể xảy ra). Là viết tắt của {0,} .

Điều đó có nghĩa là trận đấu bằng 0 hoặc nhiều hơn Nhóm Nhóm có trước ngôi sao có thể xảy ra bất kỳ số lần nào trong văn bản. Nó có thể hoàn toàn vắng mặt hoặc lặp đi lặp lại nhiều lần.

'?'cũng là một định lượng . Là viết tắt của {0,1} .

Nó có nghĩa là "Kết hợp số không hoặc một trong các nhóm trước dấu hỏi này." Nó cũng có thể được hiểu là phần trước dấu chấm hỏi là tùy chọn .

ví dụ:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

Trong ví dụ trên '?' chỉ ra rằng hai chữ số trước nó là tùy chọn. Chúng có thể không xảy ra hoặc xảy ra nhiều nhất một lần.

Sự khác biệt giữa '.' và '?':

'.'khớp / chấp nhận / xác minh bất kỳ ký tự đơn nào cho vị trí nó đang giữ trong biểu thức chính quy.

ví dụ:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?'khớp / xác minh sự xuất hiện 0 hoặc đơn của nhóm trước nó .

Kiểm tra ví dụ số điện thoại di động.

Cùng đi với '*'. Nó sẽ kiểm tra không hoặc nhiều lần xuất hiện của nhóm trước nó .

Sự phối hợp:

'.*': Chấp nhận càng nhiều trình tự càng tốt. Cách tiếp cận tham lam .

'.*?'Chấp nhận chuỗi khớp đầu tiên và dừng lại. Cách tiếp cận không tham lam

Để biết thêm thông tin, hãy cân nhắc đọc hai câu hỏi sau ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.