Hướng dẫn how do you match a backslash in regex python? - làm cách nào để khớp dấu gạch chéo ngược trong regex python?

Một ký tự R trước biểu thức chính quy trong lệnh gọi để tìm kiếm () chỉ định rằng biểu thức chính quy là một chuỗi thô. Điều này cho phép sử dụng dấu gạch chéo ngược trong biểu thức thông thường như các ký tự thông thường hơn là trong một chuỗi các ký tự thoát. Hãy để tôi giải thích ...

Trước khi phương thức tìm kiếm của mô -đun RE xử lý các chuỗi được truyền cho nó, trình thông dịch Python sẽ vượt qua chuỗi ban đầu. Nếu có các dấu gạch chéo ngược trong một chuỗi, trình thông dịch Python phải quyết định xem mỗi người là một phần của chuỗi thoát Python (ví dụ: \ n hoặc \ t) hoặc không.

Lưu ý: Tại thời điểm này, Python không quan tâm liệu '\' có phải là một nhân vật tổng hợp biểu thức thông thường hay không.

Nếu '\' được theo sau bởi một ký tự thoát Python được công nhận (t, n, v.v.), thì dấu gạch chéo ngược và ký tự thoát được thay thế bằng ký tự unicode hoặc 8 bit thực tế. Ví dụ: '\ t' sẽ được thay thế bằng ký tự ASCII cho tab. Nếu không, nó được truyền qua và được hiểu là một nhân vật '\'.

Xem xét những điều sau đây.

>>> s = '\t'
>>> print ("[" + s  + "]")
>>> [       ]           // an actual tab character after preprocessing

>>> s = '\d'
>>> print ("[" + s  + "]")
>>> [\d]                // '\d' after preprocessing

Đôi khi chúng tôi muốn đưa vào một chuỗi một chuỗi ký tự bao gồm '\' mà không được Python hiểu là một chuỗi thoát. Để làm điều này, chúng tôi thoát khỏi '\' với '\'. Bây giờ khi Python nhìn thấy '\', nó thay thế hai dấu gạch chéo ngược bằng một ký tự '\' duy nhất.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing

Sau khi trình thông dịch Python vượt qua cả hai chuỗi, chúng được chuyển sang phương thức tìm kiếm của mô -đun RE. Phương thức tìm kiếm phân tích chuỗi biểu thức thông thường để xác định các ký tự meta của biểu thức thông thường.

Bây giờ '\' cũng là một nhân vật tổng hợp biểu thức thông thường đặc biệt và được hiểu là một trừ khi nó được thoát ra tại thời điểm phương thức tìm kiếm RE () được thực thi.

Xem xét cuộc gọi sau.

>>> match = re.search('a\\t','a\\t')        //Match is None

Ở đây, trận đấu là không có. Tại sao? Hãy nhìn vào các chuỗi sau khi thông dịch viên Python thực hiện vượt qua.

String 1: 'a\t'
String 2: 'a\t' 

Vậy tại sao khớp với không có? Khi search () diễn giải chuỗi 1, vì nó là một biểu thức chính quy, dấu gạch chéo ngược được hiểu là một nhân vật tổng hợp, không phải là một ký tự thông thường. Tuy nhiên, dấu gạch chéo ngược trong chuỗi 2 không nằm trong một biểu thức thông thường và đã được trình thông dịch Python xử lý, vì vậy nó được hiểu là một ký tự thông thường.

Vì vậy, phương thức search () đang tìm kiếm 'A Escape-t' trong chuỗi 'a \ t' không phải là một trận đấu.

Để khắc phục điều này, chúng ta có thể nói cho phương thức search () để không giải thích '\' như một nhân vật tổng hợp. Chúng ta có thể làm điều này bằng cách thoát khỏi nó.

Xem xét cuộc gọi sau.

Ở đây, trận đấu là không có. Tại sao? Hãy nhìn vào các chuỗi sau khi thông dịch viên Python thực hiện vượt qua.

Vậy tại sao khớp với không có? Khi search () diễn giải chuỗi 1, vì nó là một biểu thức chính quy, dấu gạch chéo ngược được hiểu là một nhân vật tổng hợp, không phải là một ký tự thông thường. Tuy nhiên, dấu gạch chéo ngược trong chuỗi 2 không nằm trong một biểu thức thông thường và đã được trình thông dịch Python xử lý, vì vậy nó được hiểu là một ký tự thông thường.

String 1: 'a\\t'
String 2: 'a\t'

Vì vậy, phương thức search () đang tìm kiếm 'A Escape-t' trong chuỗi 'a \ t' không phải là một trận đấu.

Để khắc phục điều này, chúng ta có thể nói cho phương thức search () để không giải thích '\' như một nhân vật tổng hợp. Chúng ta có thể làm điều này bằng cách thoát khỏi nó.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'

Một lần nữa, hãy nhìn vào các chuỗi sau khi phiên dịch viên Python đã vượt qua.

String 1: 'a\\t'
String 2: 'a\t'

Bây giờ khi phương thức tìm kiếm () xử lý biểu thức chính quy, nó thấy rằng dấu gạch chéo ngược thứ hai được thoát ra bởi phương pháp thứ nhất và không nên được coi là một nhân vật tổng hợp. Do đó, nó diễn giải chuỗi là 'a \ t', phù hợp với chuỗi 2.

Tác giả

SÁNG. Kuchling@amk.ca>

trừu tượng

Tài liệu này là một hướng dẫn giới thiệu để sử dụng các biểu thức chính quy trong Python với mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3. Nó cung cấp một giới thiệu nhẹ nhàng hơn phần tương ứng trong tài liệu tham khảo thư viện.

Giới thiệu¶

Các biểu thức chính quy (được gọi là RES, hoặc các mẫu Regexes hoặc Regex) về cơ bản là một ngôn ngữ lập trình nhỏ, chuyên dụng cao được nhúng bên trong Python và được cung cấp thông qua mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3. Sử dụng ngôn ngữ nhỏ này, bạn chỉ định các quy tắc cho tập hợp các chuỗi có thể mà bạn muốn khớp; Bộ này có thể chứa các câu tiếng Anh hoặc địa chỉ e-mail hoặc lệnh tex hoặc bất cứ điều gì bạn thích. Sau đó, bạn có thể đặt câu hỏi như là chuỗi này có phù hợp với mẫu không? Bạn cũng có thể sử dụng RES để sửa đổi một chuỗi hoặc để tách nó ra theo nhiều cách khác nhau.

Các mẫu biểu thức chính quy được biên dịch thành một loạt các byte sau đó được thực hiện bởi một công cụ phù hợp được viết bằng C. Để sử dụng nâng cao, có thể cần phải chú ý cẩn thận đến cách động cơ sẽ thực hiện một RE đã cho và viết RE trong A Cách nhất định để sản xuất mã byte chạy nhanh hơn. Tối ưu hóa không được đề cập trong tài liệu này, bởi vì nó đòi hỏi bạn phải hiểu rõ về nội bộ động cơ phù hợp.

Ngôn ngữ biểu thức chính quy tương đối nhỏ và bị hạn chế, vì vậy không phải tất cả các tác vụ xử lý chuỗi có thể có thể được thực hiện bằng cách sử dụng các biểu thức thông thường. Ngoài ra còn có các nhiệm vụ có thể được thực hiện với các biểu thức thông thường, nhưng các biểu thức hóa ra rất phức tạp. Trong những trường hợp này, bạn có thể tốt hơn khi viết mã Python để thực hiện xử lý; Mặc dù mã Python sẽ chậm hơn một biểu thức thông thường phức tạp, nhưng nó cũng có thể dễ hiểu hơn.

Các mẫu đơn giản

Chúng tôi sẽ bắt đầu bằng cách tìm hiểu về các biểu thức chính quy đơn giản nhất có thể. Vì các biểu thức thông thường được sử dụng để hoạt động trên các chuỗi, chúng tôi sẽ bắt đầu với nhiệm vụ phổ biến nhất: các ký tự phù hợp.

Để giải thích chi tiết về khoa học máy tính theo các biểu thức thường xuyên (tự động tự nhiên xác định và không xác định), bạn có thể tham khảo hầu hết mọi cuốn sách giáo khoa về viết trình biên dịch.

Các ký tự phù hợp

Hầu hết các chữ cái và ký tự sẽ đơn giản phù hợp với chính họ. Ví dụ: biểu thức thông thường

String 1: 'a\\t'
String 2: 'a\t'
5 sẽ khớp chính xác với chuỗi
String 1: 'a\\t'
String 2: 'a\t'
5. .

Có những trường hợp ngoại lệ cho quy tắc này; Một số nhân vật là những người metacharacters đặc biệt, và don lồng phù hợp với chính họ. Thay vào đó, họ báo hiệu rằng một số điều ngoài tầm thường nên được khớp hoặc chúng ảnh hưởng đến các phần khác của RE bằng cách lặp lại chúng hoặc thay đổi ý nghĩa của chúng. Phần lớn tài liệu này được dành để thảo luận về các metacharacters khác nhau và những gì họ làm.

Ở đây, một danh sách đầy đủ các metacharacters; Ý nghĩa của chúng sẽ được thảo luận trong phần còn lại của howto này.

. ^ $ * + ? { } [ ] \ | ( )

Các metacharacters đầu tiên mà chúng tôi sẽ xem xét là

String 1: 'a\\t'
String 2: 'a\t'
9 và
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
0. Chúng được sử dụng để chỉ định một lớp ký tự, đó là một tập hợp các ký tự mà bạn muốn phù hợp. Các ký tự có thể được liệt kê riêng lẻ hoặc một loạt các ký tự có thể được chỉ định bằng cách đưa hai ký tự và tách chúng bằng một
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
1. Ví dụ:
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
2 sẽ khớp với bất kỳ ký tự nào
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
3,
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4 hoặc
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
5; Điều này giống như
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
6, sử dụng một phạm vi để thể hiện cùng một tập hợp các ký tự. Nếu bạn chỉ muốn khớp với các chữ cái viết thường, RE của bạn sẽ là
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
7.

Metacharacters (trừ

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
8) không hoạt động trong các lớp. Ví dụ:
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
9 sẽ khớp với bất kỳ ký tự nào
String 1: 'a\\t'
String 2: 'a\t'
0,
String 1: 'a\\t'
String 2: 'a\t'
1,
String 1: 'a\\t'
String 2: 'a\t'
2 hoặc
String 1: 'a\\t'
String 2: 'a\t'
3;
String 1: 'a\\t'
String 2: 'a\t'
3 thường là một metacharacter, nhưng bên trong một lớp nhân vật, nó đã tước bỏ bản chất đặc biệt của nó.

Bạn có thể khớp các ký tự không được liệt kê trong lớp bằng cách bổ sung cho tập hợp. Điều này được biểu thị bằng cách bao gồm một

String 1: 'a\\t'
String 2: 'a\t'
5 là nhân vật đầu tiên của lớp. Ví dụ:
String 1: 'a\\t'
String 2: 'a\t'
6 sẽ khớp với bất kỳ ký tự nào ngoại trừ
String 1: 'a\\t'
String 2: 'a\t'
7. Nếu Caret xuất hiện ở nơi khác trong một lớp nhân vật, nó không có ý nghĩa đặc biệt. Ví dụ:
String 1: 'a\\t'
String 2: 'a\t'
8 sẽ khớp với
String 1: 'a\\t'
String 2: 'a\t'
7 hoặc
String 1: 'a\\t'
String 2: 'a\t'
5.

Có lẽ metacharacter quan trọng nhất là dấu gạch chéo ngược,

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
8. Như trong Python String Ligenals, dấu gạch chéo ngược có thể được theo sau bởi các ký tự khác nhau để báo hiệu các chuỗi đặc biệt khác nhau. Nó cũng được sử dụng để thoát khỏi tất cả các metacharacters để bạn vẫn có thể kết hợp chúng theo các mẫu; Ví dụ: nếu bạn cần khớp với
String 1: 'a\\t'
String 2: 'a\t'
9 hoặc
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
8, bạn có thể đi trước chúng bằng một dấu gạch chéo ngược để loại bỏ ý nghĩa đặc biệt của chúng:
. ^ $ * + ? { } [ ] \ | ( )
4 hoặc
. ^ $ * + ? { } [ ] \ | ( )
5.

Một số chuỗi đặc biệt bắt đầu bằng

. ^ $ * + ? { } [ ] \ | ( )
6 đại diện cho các bộ ký tự được xác định trước thường hữu ích, chẳng hạn như tập hợp các chữ số, tập hợp các chữ cái hoặc tập hợp bất cứ thứ gì là khoảng trắng.

Hãy để lấy một ví dụ:

. ^ $ * + ? { } [ ] \ | ( )
7 khớp với bất kỳ ký tự chữ và số nào. Nếu mẫu regex được thể hiện bằng byte, thì điều này tương đương với lớp
. ^ $ * + ? { } [ ] \ | ( )
8. Nếu mẫu regex là một chuỗi,
. ^ $ * + ? { } [ ] \ | ( )
7 sẽ khớp với tất cả các ký tự được đánh dấu là các chữ cái trong cơ sở dữ liệu Unicode được cung cấp bởi mô -đun
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
0. Bạn có thể sử dụng định nghĩa hạn chế hơn của
. ^ $ * + ? { } [ ] \ | ( )
7 trong một mẫu chuỗi bằng cách cung cấp cờ
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
2 khi biên dịch biểu thức thông thường.

Danh sách sau đây các chuỗi đặc biệt là hoàn thành. Để biết danh sách đầy đủ các chuỗi và các định nghĩa lớp mở rộng cho các mẫu chuỗi Unicode, hãy xem phần cuối cùng của cú pháp biểu thức chính quy trong tham chiếu thư viện tiêu chuẩn. Nói chung, các phiên bản Unicode phù hợp với bất kỳ ký tự nào mà trong danh mục thích hợp trong cơ sở dữ liệu Unicode.Regular Expression Syntax in the Standard Library reference. In general, the Unicode versions match any character that’s in the appropriate category in the Unicode database.

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
3

Phù hợp với bất kỳ chữ số thập phân; Điều này tương đương với lớp

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
4.

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
5

Khớp với bất kỳ ký tự không chữ số nào; Điều này tương đương với lớp

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
6.

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
7

Phù hợp với bất kỳ ký tự khoảng trắng nào; Điều này tương đương với lớp

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
8.

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
9

Phù hợp với bất kỳ ký tự không phải là màu sắc nào; Điều này tương đương với lớp

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
00.

. ^ $ * + ? { } [ ] \ | ( )
7

Phù hợp với bất kỳ ký tự chữ và số nào; Điều này tương đương với lớp

. ^ $ * + ? { } [ ] \ | ( )
8.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
03

Phù hợp với bất kỳ ký tự không phải là đồngumeric; Điều này tương đương với lớp

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
04.

Các chuỗi này có thể được bao gồm bên trong một lớp ký tự. Ví dụ:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
05 là một lớp ký tự sẽ phù hợp với bất kỳ ký tự khoảng trắng nào hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
06 hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
07.

Metacharacter cuối cùng trong phần này là

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
08. Nó phù hợp với bất cứ điều gì ngoại trừ một ký tự mới và có một chế độ thay thế (
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
09) nơi nó sẽ phù hợp với ngay cả một dòng mới.
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
08 thường được sử dụng ở nơi bạn muốn khớp với bất kỳ nhân vật nào.

Lặp lại mọi thứ

Có thể khớp với các bộ ký tự khác nhau là điều đầu tiên các biểu thức chính quy có thể làm điều đó là có thể với các phương thức có sẵn trên các chuỗi. Tuy nhiên, nếu đó là khả năng bổ sung duy nhất của Regexes, thì họ sẽ không phải là một tiến bộ. Một khả năng khác là bạn có thể chỉ định rằng các phần của RE phải được lặp lại một số lần nhất định.

Metacharacter đầu tiên để lặp lại những thứ mà chúng tôi sẽ xem xét là

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11.
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11 không phù hợp với ký tự theo nghĩa đen
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
13; Thay vào đó, nó chỉ định rằng ký tự trước có thể được khớp với 0 hoặc nhiều lần, thay vì chính xác một lần.

Ví dụ:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
14 sẽ khớp với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
15 (0
String 1: 'a\\t'
String 2: 'a\t'
0 ký tự),
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
17 (1
String 1: 'a\\t'
String 2: 'a\t'
0),
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
19 (3 ​​
String 1: 'a\\t'
String 2: 'a\t'
0 ký tự), v.v.

Sự lặp lại như

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11 là tham lam; Khi lặp lại một RE, động cơ phù hợp sẽ cố gắng lặp lại nó càng nhiều lần càng tốt. Nếu các phần sau của mẫu don don phù hợp, động cơ phù hợp sau đó sẽ sao lưu và thử lại với ít sự lặp lại hơn.

Một ví dụ từng bước sẽ làm cho điều này rõ ràng hơn. Hãy cùng xem xét biểu thức

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
22. Điều này phù hợp với chữ cái
String 1: 'a\\t'
String 2: 'a\t'
0, không hoặc nhiều chữ cái từ lớp
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
24 và cuối cùng kết thúc bằng một
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
25. Bây giờ hãy tưởng tượng phù hợp với RE này với chuỗi
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
26.

Bươc

Phù hợp

Giải trình

1

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
3

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
3 trong các trận đấu RE.

2

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
29

Động cơ phù hợp với

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
30, đi xa nhất có thể, đến cuối chuỗi.

3

Thất bại

Động cơ cố gắng phù hợp với

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4, nhưng vị trí hiện tại ở cuối chuỗi, vì vậy nó không thành công.

4

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
32

Sao lưu, để

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
30 phù hợp với một ký tự ít hơn.

5

Thất bại

Động cơ cố gắng phù hợp với

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4, nhưng vị trí hiện tại ở cuối chuỗi, vì vậy nó không thành công.

6

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
36

Sao lưu, để

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
30 phù hợp với một ký tự ít hơn.

6

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
32

Hãy thử một lần nữa, nhưng vị trí hiện tại là ở ký tự cuối cùng, đó là một

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
35.

Sao lưu lại, để

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
30 chỉ khớp với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
38.

Hãy thử lại

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4. Lần này, nhân vật ở vị trí hiện tại là
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
25, vì vậy nó thành công.

Sự kết thúc của RE đã đạt được và nó đã khớp với

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
42. Điều này cho thấy làm thế nào động cơ phù hợp đi xa nhất có thể, và nếu không tìm thấy trận đấu nào thì thì sẽ dần dần sao lưu và thử lại phần còn lại của RE nhiều lần. Nó sẽ sao lưu cho đến khi nó đã thử các trận đấu bằng không cho
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
30 và nếu điều đó sau đó không thành công, động cơ sẽ kết luận rằng chuỗi không phù hợp với RE.

Một metacharacter lặp lại khác là

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44, phù hợp với một hoặc nhiều lần. Hãy chú ý cẩn thận đến sự khác biệt giữa
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11 và
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44;
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11 khớp với số lần hoặc nhiều lần, vì vậy, bất cứ điều gì mà Lôi được lặp lại đều có thể không có mặt, trong khi
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44 yêu cầu ít nhất một lần xuất hiện. Để sử dụng một ví dụ tương tự,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
49 sẽ khớp với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
17 (1
String 1: 'a\\t'
String 2: 'a\t'
0),
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
19 (3 ​​
String 1: 'a\\t'
String 2: 'a\t'
0s), nhưng đã giành được trận đấu
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
15.

Có hai toán tử hoặc định lượng lặp lại. Ký tự dấu câu hỏi,

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55, khớp với một lần hoặc bằng không; Bạn có thể nghĩ về nó là đánh dấu một cái gì đó là tùy chọn. Ví dụ:
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
56 khớp với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
57 hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
58.

Bộ định lượng phức tạp nhất là

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
59, trong đó m và n là số nguyên thập phân. Định lượng này có nghĩa là phải có ít nhất m lần lặp lại, và nhiều nhất là n. Ví dụ:
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
60 sẽ khớp với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
61,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
62 và
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
63. Nó đã thắng trận đấu
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
64, không có dấu gạch chéo, hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
65, có bốn.

Bạn có thể bỏ qua m hoặc n; Trong trường hợp đó, một giá trị hợp lý được giả định cho giá trị bị thiếu. Bỏ qua M được hiểu là giới hạn thấp hơn 0, trong khi bỏ qua N dẫn đến giới hạn trên của vô cực.

Độc giả của một người bị giảm bớt có thể nhận thấy rằng ba định lượng khác đều có thể được thể hiện bằng cách sử dụng ký hiệu này.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
66 giống như
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
68 tương đương với
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44 và
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
70 giống như
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55. Nó tốt hơn để sử dụng
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44 hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55 khi bạn có thể, chỉ vì chúng ngắn hơn và dễ đọc hơn.

Sử dụng các biểu thức thông thường

Bây giờ chúng tôi đã xem xét một số biểu thức thông thường đơn giản, làm thế nào để chúng ta thực sự sử dụng chúng trong Python? Mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3 cung cấp một giao diện cho công cụ biểu thức chính quy, cho phép bạn biên dịch RES vào các đối tượng và sau đó thực hiện các trận đấu với chúng.

>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')

Biên soạn các biểu thức chính quy

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
0

Các biểu thức chính quy được biên dịch thành các đối tượng mẫu, có các phương thức cho các hoạt động khác nhau như tìm kiếm các kết quả phù hợp mẫu hoặc thực hiện thay thế chuỗi.

Đặt res vào các chuỗi giữ cho ngôn ngữ Python đơn giản hơn, nhưng có một nhược điểm đó là chủ đề của phần tiếp theo.

Bệnh dịch hạch ngược

Như đã nêu trước đó, các biểu thức chính quy sử dụng ký tự dấu gạch chéo ngược (

. ^ $ * + ? { } [ ] \ | ( )
6) để biểu thị các hình thức đặc biệt hoặc cho phép các ký tự đặc biệt được sử dụng mà không cần gọi ý nghĩa đặc biệt của chúng. Điều này mâu thuẫn với việc sử dụng Python sườn của cùng một nhân vật cho cùng một mục đích trong các chữ viết.

Hãy nói rằng bạn muốn viết một RE phù hợp với chuỗi

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
82, có thể được tìm thấy trong một tệp latex. Để tìm ra những gì cần viết trong mã chương trình, hãy bắt đầu với chuỗi mong muốn được khớp. Tiếp theo, bạn phải thoát khỏi bất kỳ dấu gạch chéo ngược nào và các metacharacters khác bằng cách trước chúng bằng một dấu gạch chéo ngược, dẫn đến chuỗi
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
83. Chuỗi kết quả phải được chuyển đến
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
76 phải là
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
83. Tuy nhiên, để thể hiện điều này như một chuỗi Python theo nghĩa đen, cả hai dấu gạch chéo ngược phải được thoát ra một lần nữa.

Nhân vật

Sân khấu

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
82

Chuỗi văn bản được khớp

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
83

Đã thoát khỏi sự chéo ngược cho

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
76

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
89

Thoát khỏi sự chéo ngược cho một chuỗi theo nghĩa đen

Nói tóm lại, để phù hợp với một dấu gạch chéo ngược theo nghĩa đen, người ta phải viết

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
90 dưới dạng chuỗi RE, bởi vì biểu thức thông thường phải là
. ^ $ * + ? { } [ ] \ | ( )
5 và mỗi dấu gạch chéo ngược phải được biểu thị dưới dạng
. ^ $ * + ? { } [ ] \ | ( )
5 bên trong một chuỗi python thông thường theo nghĩa đen. Trong RES đó là các dấu gạch chéo ngược nhiều lần, điều này dẫn đến rất nhiều dấu gạch chéo ngược lặp đi lặp lại và làm cho các chuỗi kết quả khó hiểu.

Giải pháp là sử dụng ký hiệu chuỗi thô Python sườn cho các biểu thức thông thường; Backslashes không được xử lý theo bất kỳ cách đặc biệt nào trong một chuỗi theo nghĩa đen được đặt trước với

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
93, vì vậy
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
94 là một chuỗi hai nhân vật chứa
. ^ $ * + ? { } [ ] \ | ( )
6 và
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
96, trong khi
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
97 là chuỗi một ký tự có chứa một dòng mới. Biểu thức chính quy thường sẽ được viết bằng mã Python bằng cách sử dụng ký hiệu chuỗi thô này.

Ngoài ra, các chuỗi thoát đặc biệt có giá trị trong các biểu thức chính quy, nhưng không hợp lệ như các chữ Python, bây giờ dẫn đến

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
98 và cuối cùng sẽ trở thành
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
99, điều đó có nghĩa là các chuỗi sẽ không hợp lệ nếu ký hiệu chuỗi thô hoặc thoát khỏi các dấu gạch chéo ngược không phải là ' t sử dụng.

Chuỗi thông thường

Chuỗi thô

>>> match = re.search('a\\t','a\\t')        //Match is None
00

>>> match = re.search('a\\t','a\\t')        //Match is None
01

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
89

>>> match = re.search('a\\t','a\\t')        //Match is None
03

>>> match = re.search('a\\t','a\\t')        //Match is None
04

>>> match = re.search('a\\t','a\\t')        //Match is None
05

Thực hiện các trận đấu

Khi bạn có một đối tượng đại diện cho một biểu thức thông thường được biên dịch, bạn sẽ làm gì với nó? Đối tượng mẫu có một số phương thức và thuộc tính. Chỉ những người quan trọng nhất sẽ được đề cập ở đây; Tham khảo các tài liệu

String 1: 'a\\t'
String 2: 'a\t'
3 để biết danh sách đầy đủ.

Method/Attribute

Mục đích

>>> match = re.search('a\\t','a\\t')        //Match is None
07

Xác định xem RE có khớp ở đầu chuỗi không.

>>> match = re.search('a\\t','a\\t')        //Match is None
08

Quét qua một chuỗi, tìm kiếm bất kỳ vị trí nào mà điều này phù hợp.

>>> match = re.search('a\\t','a\\t')        //Match is None
09

Tìm tất cả các chuỗi con nơi RE khớp với nhau và trả về chúng dưới dạng danh sách.

>>> match = re.search('a\\t','a\\t')        //Match is None
10

Tìm tất cả các chuỗi con nơi RE khớp với nhau và trả về chúng như một trình lặp lại.iterator.

>>> match = re.search('a\\t','a\\t')        //Match is None
07 và
>>> match = re.search('a\\t','a\\t')        //Match is None
08 Trả về
>>> match = re.search('a\\t','a\\t')        //Match is None
13 nếu không thể tìm thấy trận đấu. Nếu họ thành công, một thể hiện đối tượng phù hợp được trả về, chứa thông tin về trận đấu: nơi nó bắt đầu và kết thúc, phần phụ mà nó khớp và hơn thế nữa.match object instance is returned, containing information about the match: where it starts and ends, the substring it matched, and more.

Bạn có thể tìm hiểu về điều này bằng cách thử nghiệm tương tác với mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3. Nếu bạn có sẵn
>>> match = re.search('a\\t','a\\t')        //Match is None
15, bạn cũng có thể muốn xem các công cụ/demo/redemo.py, một chương trình trình diễn có trong phân phối Python. Nó cho phép bạn nhập RES và chuỗi, và hiển thị cho dù RE khớp hay thất bại.
>>> match = re.search('a\\t','a\\t')        //Match is None
16 có thể khá hữu ích khi cố gắng gỡ lỗi RE phức tạp.

Howto này sử dụng trình thông dịch Python tiêu chuẩn cho các ví dụ của nó. Đầu tiên, chạy trình thông dịch Python, nhập mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3 và biên dịch một Re:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
1

Bây giờ, bạn có thể thử khớp các chuỗi khác nhau với RE

>>> match = re.search('a\\t','a\\t')        //Match is None
18. Một chuỗi trống không nên khớp với nhau, vì
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44 có nghĩa là một hoặc nhiều lần lặp lại.
>>> match = re.search('a\\t','a\\t')        //Match is None
07 sẽ trả về
>>> match = re.search('a\\t','a\\t')        //Match is None
13 trong trường hợp này, điều này sẽ khiến thông dịch viên không in đầu ra. Bạn có thể in rõ ràng kết quả của
>>> match = re.search('a\\t','a\\t')        //Match is None
07 để làm rõ điều này.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
2

Bây giờ, hãy để thử nó trên một chuỗi mà nó sẽ phù hợp, chẳng hạn như

>>> match = re.search('a\\t','a\\t')        //Match is None
23. Trong trường hợp này,
>>> match = re.search('a\\t','a\\t')        //Match is None
07 sẽ trả về một đối tượng khớp, vì vậy bạn nên lưu trữ kết quả trong một biến để sử dụng sau.match object, so you should store the result in a variable for later use.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
3

Bây giờ bạn có thể truy vấn đối tượng khớp để biết thông tin về chuỗi khớp. Các trường hợp đối tượng khớp cũng có một số phương thức và thuộc tính; Những cái quan trọng nhất là:match object for information about the matching string. Match object instances also have several methods and attributes; the most important ones are:

Method/Attribute

Mục đích

>>> match = re.search('a\\t','a\\t')        //Match is None
25

Xác định xem RE có khớp ở đầu chuỗi không.

>>> match = re.search('a\\t','a\\t')        //Match is None
26

Quét qua một chuỗi, tìm kiếm bất kỳ vị trí nào mà điều này phù hợp.

>>> match = re.search('a\\t','a\\t')        //Match is None
27

Tìm tất cả các chuỗi con nơi RE khớp với nhau và trả về chúng dưới dạng danh sách.

>>> match = re.search('a\\t','a\\t')        //Match is None
28

Trả về một tuple chứa các vị trí (bắt đầu, kết thúc) của trận đấu

Thử các phương pháp này sẽ sớm làm rõ ý nghĩa của chúng:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
4

>>> match = re.search('a\\t','a\\t')        //Match is None
25 Trả về phần con được kết hợp bởi RE.
>>> match = re.search('a\\t','a\\t')        //Match is None
26 và
>>> match = re.search('a\\t','a\\t')        //Match is None
27 Trả về chỉ số bắt đầu và kết thúc của trận đấu.
>>> match = re.search('a\\t','a\\t')        //Match is None
28 Trả về cả hai chỉ mục bắt đầu và kết thúc trong một tuple. Vì phương thức
>>> match = re.search('a\\t','a\\t')        //Match is None
07 chỉ kiểm tra xem RE có khớp khi bắt đầu chuỗi hay không,
>>> match = re.search('a\\t','a\\t')        //Match is None
26 sẽ luôn bằng không. Tuy nhiên, phương pháp
>>> match = re.search('a\\t','a\\t')        //Match is None
08 của các mẫu quét qua chuỗi, do đó, trận đấu có thể không bắt đầu ở mức 0 trong trường hợp đó.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
5

Trong các chương trình thực tế, phong cách phổ biến nhất là lưu trữ đối tượng khớp trong một biến, sau đó kiểm tra xem nó có phải là

>>> match = re.search('a\\t','a\\t')        //Match is None
13 không. Điều này thường trông giống như:match object in a variable, and then check if it was
>>> match = re.search('a\\t','a\\t')        //Match is None
13. This usually looks like:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
6

Hai phương thức mẫu trả về tất cả các trận đấu cho một mẫu.

>>> match = re.search('a\\t','a\\t')        //Match is None
09 Trả về danh sách các chuỗi phù hợp:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
7

Tiền tố

>>> match = re.search('a\\t','a\\t')        //Match is None
38, làm cho chữ theo nghĩa đen, là cần thiết trong ví dụ này bởi vì các chuỗi thoát trong một chuỗi theo nghĩa đen được nấu chín bình thường mà không được Python nhận ra, trái ngược với các biểu thức thông thường, bây giờ dẫn đến
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
98 và cuối cùng sẽ trở thành A
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
99. Xem bệnh dịch ngược.The Backslash Plague.

>>> match = re.search('a\\t','a\\t')        //Match is None
09 phải tạo toàn bộ danh sách trước khi nó có thể được trả lại do kết quả. Phương thức
>>> match = re.search('a\\t','a\\t')        //Match is None
10 trả về một chuỗi các phiên bản đối tượng khớp với tư cách là một trình lặp:match object instances as an iterator:

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
8

Các chức năng cấp độ mô-đun

Bạn không phải tạo ra một đối tượng mẫu và gọi các phương thức của nó; Mô-đun

String 1: 'a\\t'
String 2: 'a\t'
3 cũng cung cấp các chức năng cấp cao nhất được gọi là
>>> match = re.search('a\\t','a\\t')        //Match is None
07,
>>> match = re.search('a\\t','a\\t')        //Match is None
08,
>>> match = re.search('a\\t','a\\t')        //Match is None
09,
>>> match = re.search('a\\t','a\\t')        //Match is None
47, v.v. Các hàm này có cùng các đối số với phương thức mẫu tương ứng với chuỗi RE được thêm vào đối số đầu tiên và vẫn trả về
>>> match = re.search('a\\t','a\\t')        //Match is None
13 hoặc một thể hiện đối tượng khớp.match object instance.

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
9

Dưới mui xe, các chức năng này chỉ cần tạo một đối tượng mẫu cho bạn và gọi phương thức thích hợp trên đó. Họ cũng lưu trữ đối tượng được biên dịch trong bộ đệm, vì vậy các cuộc gọi trong tương lai sử dụng cùng một won won cần phải phân tích lại mẫu.

Bạn nên sử dụng các chức năng cấp mô-đun này, hoặc bạn nên tự mình lấy mẫu và gọi các phương thức của nó? Nếu bạn đang truy cập vào một regex trong một vòng lặp, việc biên dịch trước, nó sẽ lưu một vài cuộc gọi chức năng. Bên ngoài các vòng lặp, có rất nhiều sự khác biệt nhờ bộ đệm nội bộ.

Cờ tổng hợp

Cờ biên dịch cho phép bạn sửa đổi một số khía cạnh về cách thức biểu thức thường xuyên hoạt động. Cờ có sẵn trong mô-đun

String 1: 'a\\t'
String 2: 'a\t'
3 dưới hai tên, một tên dài như
>>> match = re.search('a\\t','a\\t')        //Match is None
50 và một hình thức ngắn, một chữ cái như
>>> match = re.search('a\\t','a\\t')        //Match is None
51. .
>>> match = re.search('a\\t','a\\t')        //Match is None
54 Đặt cả cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
51 và
>>> match = re.search('a\\t','a\\t')        //Match is None
56 chẳng hạn.

Ở đây, một bảng của các cờ có sẵn, tiếp theo là một lời giải thích chi tiết hơn về từng người.

Lá cờ

Nghĩa

>>> match = re.search('a\\t','a\\t')        //Match is None
57,
>>> match = re.search('a\\t','a\\t')        //Match is None
58

Làm cho một số lối thoát như

. ^ $ * + ? { } [ ] \ | ( )
7,
>>> match = re.search('a\\t','a\\t')        //Match is None
60,
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
7 và
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
3 chỉ khớp với các ký tự ASCII với thuộc tính tương ứng.

>>> match = re.search('a\\t','a\\t')        //Match is None
63,
>>> match = re.search('a\\t','a\\t')        //Match is None
64

Tạo

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
08 khớp với bất kỳ nhân vật nào, bao gồm cả dòng mới.

>>> match = re.search('a\\t','a\\t')        //Match is None
50,
>>> match = re.search('a\\t','a\\t')        //Match is None
51

Làm các trận đấu không nhạy cảm trường hợp.

>>> match = re.search('a\\t','a\\t')        //Match is None
68,
>>> match = re.search('a\\t','a\\t')        //Match is None
69

Làm một trận đấu nhận biết địa phương.

>>> match = re.search('a\\t','a\\t')        //Match is None
70,
>>> match = re.search('a\\t','a\\t')        //Match is None
56

Kết hợp đa dòng, ảnh hưởng đến

>>> match = re.search('a\\t','a\\t')        //Match is None
72 và
>>> match = re.search('a\\t','a\\t')        //Match is None
73.

>>> match = re.search('a\\t','a\\t')        //Match is None
74,
>>> match = re.search('a\\t','a\\t')        //Match is None
75 (cho ‘mở rộng)

Bật Res Verbose, có thể được tổ chức sạch sẽ và dễ hiểu hơn.

Iignorecase IGNORECASE

Thực hiện kết hợp không nhạy cảm trường hợp; lớp ký tự và chuỗi theo nghĩa đen sẽ phù hợp với các chữ cái bằng cách bỏ qua trường hợp. Ví dụ,

>>> match = re.search('a\\t','a\\t')        //Match is None
76 cũng sẽ phù hợp với các chữ cái viết thường. Kết hợp toàn bộ Unicode cũng hoạt động trừ khi cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
57 được sử dụng để vô hiệu hóa các trận đấu không ASCII. Khi các mẫu Unicode
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
7 hoặc
>>> match = re.search('a\\t','a\\t')        //Match is None
76 được sử dụng kết hợp với cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
50, chúng sẽ khớp với 52 chữ cái ASCII và 4 chữ cái không ASCII bổ sung: ' '(U+0131, chữ nhỏ Latin không có dấu chấm i),' ſ '(u+017f, chữ nhỏ Latin dài s) và' k '(u+212a, dấu hiệu Kelvin).
>>> match = re.search('a\\t','a\\t')        //Match is None
81 sẽ khớp với
>>> match = re.search('a\\t','a\\t')        //Match is None
82,
>>> match = re.search('a\\t','a\\t')        //Match is None
83,
>>> match = re.search('a\\t','a\\t')        //Match is None
84 hoặc
>>> match = re.search('a\\t','a\\t')        //Match is None
85 (cái sau chỉ khớp với chế độ Unicode). Lowercasing này không tính đến địa phương hiện tại; Nó sẽ nếu bạn cũng đặt cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
68.

LLOCALE LOCALE

Tạo

. ^ $ * + ? { } [ ] \ | ( )
7,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
03,
>>> match = re.search('a\\t','a\\t')        //Match is None
60,
>>> match = re.search('a\\t','a\\t')        //Match is None
90 và khớp không nhạy cảm với trường hợp phụ thuộc vào ngôn ngữ hiện tại thay vì cơ sở dữ liệu Unicode.

Các địa phương là một tính năng của thư viện C nhằm giúp viết các chương trình có tính đến sự khác biệt ngôn ngữ. Ví dụ: nếu bạn xử lý văn bản Pháp được mã hóa, bạn sẽ muốn có thể viết

>>> match = re.search('a\\t','a\\t')        //Match is None
91 để khớp các từ, nhưng
. ^ $ * + ? { } [ ] \ | ( )
7 chỉ khớp với lớp ký tự
>>> match = re.search('a\\t','a\\t')        //Match is None
93 trong các mẫu byte; Nó đã giành chiến thắng trong các byte trận đấu tương ứng với
>>> match = re.search('a\\t','a\\t')        //Match is None
94 hoặc
>>> match = re.search('a\\t','a\\t')        //Match is None
95. Nếu hệ thống của bạn được cấu hình đúng và một địa phương Pháp được chọn, một số chức năng C nhất định sẽ cho chương trình biết rằng byte tương ứng với
>>> match = re.search('a\\t','a\\t')        //Match is None
94 cũng nên được coi là một lá thư. Đặt cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
68 khi biên dịch biểu thức chính quy sẽ khiến đối tượng được biên dịch kết quả sử dụng các hàm C này cho
. ^ $ * + ? { } [ ] \ | ( )
7; Điều này chậm hơn, nhưng cũng cho phép
>>> match = re.search('a\\t','a\\t')        //Match is None
91 phù hợp với các từ tiếng Pháp như bạn mong đợi. Việc sử dụng lá cờ này không được khuyến khích trong Python 3 vì cơ chế địa phương rất không đáng tin cậy, nó chỉ xử lý một nền văn hóa của người Hồi giáo tại một thời điểm và nó chỉ hoạt động với các địa phương 8 bit. Kết hợp Unicode đã được bật theo mặc định trong Python 3 cho các mẫu Unicode (STR) và nó có thể xử lý các địa phương/ngôn ngữ khác nhau.

Mmultiline MULTILINE

.More Metacharacters.)

Thông thường

>>> match = re.search('a\\t','a\\t')        //Match is None
72 chỉ khớp chỉ ở đầu chuỗi và
>>> match = re.search('a\\t','a\\t')        //Match is None
73 chỉ khớp ở cuối chuỗi và ngay trước dòng mới (nếu có) ở cuối chuỗi. Khi cờ này được chỉ định,
>>> match = re.search('a\\t','a\\t')        //Match is None
72 khớp ở đầu chuỗi và ở đầu mỗi dòng trong chuỗi, ngay lập tức theo từng dòng mới. Tương tự, metacharacter
>>> match = re.search('a\\t','a\\t')        //Match is None
73 khớp với cuối chuỗi và ở cuối mỗi dòng (ngay trước mỗi dòng mới).

Sdotall DOTALL

Làm cho nhân vật đặc biệt

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
07 khớp với bất kỳ nhân vật nào, bao gồm cả dòng mới; Không có cờ này,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
07 sẽ khớp với bất cứ điều gì ngoại trừ một dòng mới.

Aascii ASCII

Tạo

. ^ $ * + ? { } [ ] \ | ( )
7,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
03,
>>> match = re.search('a\\t','a\\t')        //Match is None
60,
>>> match = re.search('a\\t','a\\t')        //Match is None
90,
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
7 và
>>> import re
>>> p = re.compile('ab*')
>>> p
re.compile('ab*')
9 thực hiện kết hợp ASCII-chỉ thay vì khớp unicode đầy đủ. Điều này chỉ có ý nghĩa đối với các mẫu Unicode và bị bỏ qua cho các mẫu byte.

Xverbose VERBOSE

Cờ này cho phép bạn viết các biểu thức thông thường dễ đọc hơn bằng cách cấp cho bạn sự linh hoạt hơn trong cách bạn có thể định dạng chúng. Khi lá cờ này đã được chỉ định, khoảng trắng trong chuỗi RE bị bỏ qua, ngoại trừ khi khoảng trắng nằm trong một lớp ký tự hoặc đi trước bởi một dấu gạch chéo ngược không được điều chỉnh; Điều này cho phép bạn tổ chức và thụt vào RE rõ ràng hơn. Cờ này cũng cho phép bạn đặt bình luận trong một RE sẽ bị động cơ bỏ qua; Nhận xét được đánh dấu bằng một

String 1: 'a\t'
String 2: 'a\t' 
14 mà không có trong một lớp ký tự hoặc trước một dấu gạch chéo ngược không được phân loại.

Ví dụ, ở đây, một RE sử dụng

>>> match = re.search('a\\t','a\\t')        //Match is None
52; Xem đọc dễ dàng hơn bao nhiêu?

>>> match = re.search('a\\t','a\\t')        //Match is None
0

Nếu không có cài đặt dài dòng, RE sẽ trông như thế này:

>>> match = re.search('a\\t','a\\t')        //Match is None
1

Trong ví dụ trên, sự kết nối tự động của các chuỗi chuỗi Python đã được sử dụng để chia RE thành các phần nhỏ hơn, nhưng nó vẫn khó hiểu hơn so với phiên bản sử dụng

>>> match = re.search('a\\t','a\\t')        //Match is None
52.

Thêm Mẫu Power¶

Cho đến nay, chúng tôi chỉ bao gồm một phần các tính năng của các biểu thức thông thường. Trong phần này, chúng tôi sẽ bao gồm một số Metacharacters mới và cách sử dụng các nhóm để truy xuất các phần của văn bản được khớp.

Thêm Metacharacters¶

Có một số metacharacters mà chúng tôi đã bảo vệ. Hầu hết trong số họ sẽ được đề cập trong phần này.

Một số metacharacters còn lại sẽ được thảo luận là các xác nhận không có chiều rộng. Họ không làm cho động cơ tiến qua chuỗi; Thay vào đó, họ không tiêu thụ nhân vật nào cả, và chỉ đơn giản là thành công hay thất bại. Ví dụ,

>>> match = re.search('a\\t','a\\t')        //Match is None
60 là một khẳng định rằng vị trí hiện tại được đặt tại một ranh giới từ; Vị trí này không được thay đổi bởi
>>> match = re.search('a\\t','a\\t')        //Match is None
60. Điều này có nghĩa là các xác nhận không có chiều rộng không nên lặp lại, bởi vì nếu chúng khớp một lần tại một vị trí nhất định, rõ ràng chúng có thể được khớp với số lần vô hạn.

String 1: 'a\t'
String 2: 'a\t' 
19

Sự xen kẽ, hoặc nhà điều hành của người khác. Nếu A và B là các biểu thức thông thường,

String 1: 'a\t'
String 2: 'a\t' 
20 sẽ khớp với bất kỳ chuỗi nào khớp với A hoặc B.
String 1: 'a\t'
String 2: 'a\t' 
19 có quyền ưu tiên rất thấp để làm cho nó hoạt động hợp lý khi bạn xen kẽ các chuỗi đa nhân.
String 1: 'a\t'
String 2: 'a\t' 
22 sẽ khớp với
String 1: 'a\t'
String 2: 'a\t' 
23 hoặc
String 1: 'a\t'
String 2: 'a\t' 
24, không phải
String 1: 'a\t'
String 2: 'a\t' 
25, A
String 1: 'a\t'
String 2: 'a\t' 
26 hoặc
String 1: 'a\t'
String 2: 'a\t' 
27 và
String 1: 'a\t'
String 2: 'a\t' 
28.

Để phù hợp với nghĩa đen

String 1: 'a\t'
String 2: 'a\t' 
29, sử dụng
String 1: 'a\t'
String 2: 'a\t' 
30 hoặc đặt nó bên trong một lớp ký tự, như trong
String 1: 'a\t'
String 2: 'a\t' 
31.

>>> match = re.search('a\\t','a\\t')        //Match is None
72

Phù hợp ở đầu dòng. Trừ khi cờ

>>> match = re.search('a\\t','a\\t')        //Match is None
70 đã được đặt, điều này sẽ chỉ khớp ở đầu chuỗi. Trong chế độ
>>> match = re.search('a\\t','a\\t')        //Match is None
70, điều này cũng khớp ngay sau mỗi dòng mới trong chuỗi.

Ví dụ: nếu bạn muốn khớp từ

String 1: 'a\t'
String 2: 'a\t' 
35 chỉ ở đầu một dòng, hãy sử dụng lại là
String 1: 'a\t'
String 2: 'a\t' 
36.

>>> match = re.search('a\\t','a\\t')        //Match is None
2

Để phù hợp với nghĩa đen

String 1: 'a\\t'
String 2: 'a\t'
5, sử dụng
String 1: 'a\t'
String 2: 'a\t' 
38.

>>> match = re.search('a\\t','a\\t')        //Match is None
73

Các khớp ở cuối dòng, được định nghĩa là đầu cuối của chuỗi hoặc bất kỳ vị trí nào theo sau là ký tự dòng mới.

>>> match = re.search('a\\t','a\\t')        //Match is None
3

Để phù hợp với nghĩa đen

String 1: 'a\\t'
String 2: 'a\t'
3, hãy sử dụng
String 1: 'a\t'
String 2: 'a\t' 
41 hoặc đặt nó bên trong một lớp ký tự, như trong
String 1: 'a\t'
String 2: 'a\t' 
42.

String 1: 'a\t'
String 2: 'a\t' 
43

Chỉ khớp khi bắt đầu chuỗi. Khi không ở chế độ

>>> match = re.search('a\\t','a\\t')        //Match is None
70,
String 1: 'a\t'
String 2: 'a\t' 
43 và
>>> match = re.search('a\\t','a\\t')        //Match is None
72 có hiệu quả giống nhau. Trong chế độ
>>> match = re.search('a\\t','a\\t')        //Match is None
70, chúng khác nhau:
String 1: 'a\t'
String 2: 'a\t' 
43 vẫn chỉ khớp với đầu chuỗi, nhưng
>>> match = re.search('a\\t','a\\t')        //Match is None
72 có thể khớp tại bất kỳ vị trí nào bên trong chuỗi theo ký tự mới.

String 1: 'a\t'
String 2: 'a\t' 
50

Chỉ khớp ở cuối chuỗi.

>>> match = re.search('a\\t','a\\t')        //Match is None
60

Ranh giới từ. Đây là một khẳng định không có chiều rộng không chỉ khớp với đầu hoặc cuối của một từ. Một từ được định nghĩa là một chuỗi các ký tự chữ và số, do đó, phần cuối của một từ được biểu thị bằng khoảng trắng hoặc một ký tự không phải là vô sinh.

Ví dụ sau đây chỉ khớp với

String 1: 'a\t'
String 2: 'a\t' 
52 khi nó có một từ hoàn chỉnh; Nó đã thắng trận đấu khi nó chứa trong một từ khác.

>>> match = re.search('a\\t','a\\t')        //Match is None
4

Có hai sự tinh tế bạn nên nhớ khi sử dụng chuỗi đặc biệt này. Đầu tiên, đây là sự va chạm tồi tệ nhất giữa các chuỗi chữ Python và trình tự biểu thức chính quy. Trong các chuỗi chữ Python,

>>> match = re.search('a\\t','a\\t')        //Match is None
60 là ký tự backspace, giá trị ASCII 8. Nếu bạn không sử dụng các chuỗi thô, thì Python sẽ chuyển đổi
>>> match = re.search('a\\t','a\\t')        //Match is None
60 thành một backspace và bạn đã giành chiến thắng khi bạn mong đợi. Ví dụ sau đây trông giống như RE trước đây của chúng tôi, nhưng bỏ qua
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
93 phía trước chuỗi RE.

>>> match = re.search('a\\t','a\\t')        //Match is None
5

Thứ hai, bên trong một lớp ký tự, trong đó không có cách sử dụng cho khẳng định này,

>>> match = re.search('a\\t','a\\t')        //Match is None
60 đại diện cho ký tự backspace, để tương thích với các chữ Python tựa.

>>> match = re.search('a\\t','a\\t')        //Match is None
90

Một khẳng định không có chiều rộng khác, điều này trái ngược với

>>> match = re.search('a\\t','a\\t')        //Match is None
60, chỉ khớp khi vị trí hiện tại không ở ranh giới từ.

Nhóm

Thường thì bạn cần có thêm thông tin hơn là liệu RE có khớp hay không. Các biểu thức chính quy thường được sử dụng để mổ xẻ các chuỗi bằng cách viết một RE được chia thành một số nhóm nhỏ phù hợp với các thành phần quan tâm khác nhau. Ví dụ, dòng tiêu đề RFC-822 được chia thành tên tiêu đề và giá trị, được phân tách bằng

String 1: 'a\t'
String 2: 'a\t' 
59, như thế này:

>>> match = re.search('a\\t','a\\t')        //Match is None
6

Điều này có thể được xử lý bằng cách viết một biểu thức thông thường phù hợp với toàn bộ dòng tiêu đề và có một nhóm phù hợp với tên tiêu đề và một nhóm khác phù hợp với giá trị tiêu đề.

Các nhóm được đánh dấu bằng

String 1: 'a\t'
String 2: 'a\t' 
60,
String 1: 'a\t'
String 2: 'a\t' 
61 Metacharacters.
String 1: 'a\t'
String 2: 'a\t' 
60 và
String 1: 'a\t'
String 2: 'a\t' 
61 có nhiều ý nghĩa giống như chúng làm trong các biểu thức toán học; Chúng nhóm lại các biểu thức chứa bên trong chúng và bạn có thể lặp lại nội dung của một nhóm có bộ định lượng, chẳng hạn như
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
44,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55 hoặc
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
59. Ví dụ:
String 1: 'a\t'
String 2: 'a\t' 
68 sẽ khớp với số không hoặc nhiều sự lặp lại của
String 1: 'a\t'
String 2: 'a\t' 
69.

>>> match = re.search('a\\t','a\\t')        //Match is None
7

Các nhóm được chỉ định với

String 1: 'a\t'
String 2: 'a\t' 
60,
String 1: 'a\t'
String 2: 'a\t' 
61 cũng nắm bắt chỉ số bắt đầu và kết thúc của văn bản mà chúng phù hợp; Điều này có thể được lấy bằng cách chuyển một đối số cho
>>> match = re.search('a\\t','a\\t')        //Match is None
25,
>>> match = re.search('a\\t','a\\t')        //Match is None
26,
>>> match = re.search('a\\t','a\\t')        //Match is None
27 và
>>> match = re.search('a\\t','a\\t')        //Match is None
28. Các nhóm được đánh số bắt đầu với 0. Nhóm 0 luôn luôn có mặt; Nó có toàn bộ RE, vì vậy đều phù hợp với các phương thức đối tượng đều có nhóm 0 làm đối số mặc định của chúng. Sau đó, chúng tôi sẽ thấy cách thể hiện các nhóm không thể nắm bắt được khoảng của văn bản mà họ phù hợp.match object methods all have group 0 as their default argument. Later we’ll see how to express groups that don’t capture the span of text that they match.

>>> match = re.search('a\\t','a\\t')        //Match is None
8

Các nhóm nhỏ được đánh số từ trái sang phải, từ 1 trở lên. Các nhóm có thể được lồng nhau; Để xác định số, chỉ cần đếm các ký tự dấu ngoặc đơn, đi từ trái sang phải.

>>> match = re.search('a\\t','a\\t')        //Match is None
9

>>> match = re.search('a\\t','a\\t')        //Match is None
25 có thể được truyền nhiều số nhóm tại một thời điểm, trong trường hợp đó, nó sẽ trả về một tuple chứa các giá trị tương ứng cho các nhóm đó.

String 1: 'a\t'
String 2: 'a\t' 
0

Phương pháp

String 1: 'a\t'
String 2: 'a\t' 
77 trả về một tuple chứa các chuỗi cho tất cả các nhóm nhỏ, từ 1 trở lên tuy nhiên nhiều người có.

String 1: 'a\t'
String 2: 'a\t' 
1

Backrefer trong một mẫu cho phép bạn chỉ định rằng nội dung của một nhóm chụp trước đó cũng phải được tìm thấy tại vị trí hiện tại trong chuỗi. Ví dụ,

String 1: 'a\t'
String 2: 'a\t' 
78 sẽ thành công nếu nội dung chính xác của nhóm 1 có thể được tìm thấy ở vị trí hiện tại và không thành công. Hãy nhớ rằng các chữ Python, theo nghĩa đen cũng sử dụng dấu gạch chéo ngược, theo sau là các số để cho phép bao gồm các ký tự tùy ý trong một chuỗi, vì vậy hãy chắc chắn sử dụng một chuỗi thô khi kết hợp các bản sao lưu trong một RE.

Ví dụ: RE sau đây phát hiện các từ nhân đôi trong một chuỗi.

String 1: 'a\t'
String 2: 'a\t' 
2

Các bản sao lưu như thế này, aren thường hữu ích khi chỉ tìm kiếm qua một chuỗi - có một vài định dạng văn bản lặp lại dữ liệu theo cách này - nhưng bạn sẽ sớm phát hiện ra rằng chúng rất hữu ích khi thực hiện thay thế chuỗi.

Các nhóm không bắt giữ và được đặt tên

Xây dựng RES có thể sử dụng nhiều nhóm, cả hai để nắm bắt các nền tảng quan tâm, và để nhóm và cấu trúc chính lại. Trong Res phức tạp, việc theo dõi các số nhóm trở nên khó khăn. Có hai tính năng giúp với vấn đề này. Cả hai đều sử dụng một cú pháp chung cho các phần mở rộng biểu thức thông thường, vì vậy chúng tôi sẽ xem xét điều đó trước.

Perl 5 nổi tiếng với các bổ sung mạnh mẽ cho các biểu thức chính quy tiêu chuẩn. Đối với các tính năng mới này, các nhà phát triển Perl không thể chọn các metacharacters phát âm đơn mới hoặc các chuỗi đặc biệt mới bắt đầu bằng

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
8 mà không làm cho các biểu thức thường xuyên của Perl khác nhau một cách khó hiểu so với Res Standard. Ví dụ, nếu họ chọn
String 1: 'a\t'
String 2: 'a\t' 
80 làm metacharacter mới, các biểu thức cũ sẽ cho rằng
String 1: 'a\t'
String 2: 'a\t' 
80 là một nhân vật thường xuyên và sẽ thoát khỏi nó bằng cách viết
String 1: 'a\t'
String 2: 'a\t' 
82 hoặc
String 1: 'a\t'
String 2: 'a\t' 
83.

Giải pháp được các nhà phát triển Perl lựa chọn là sử dụng

String 1: 'a\t'
String 2: 'a\t' 
84 làm cú pháp mở rộng.
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55 ngay sau khi dấu ngoặc đơn là lỗi cú pháp vì
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55 sẽ không có gì để lặp lại, vì vậy điều này đã không đưa ra bất kỳ vấn đề tương thích nào. Các ký tự ngay sau
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
55 cho biết phần mở rộng nào đang được sử dụng, vì vậy
String 1: 'a\t'
String 2: 'a\t' 
88 là một điều (khẳng định xem xét tích cực) và
String 1: 'a\t'
String 2: 'a\t' 
89 là một cái gì đó khác (một nhóm không bắt giữ chứa biểu thức phụ
String 1: 'a\t'
String 2: 'a\t' 
90).

Python hỗ trợ một số tiện ích mở rộng Perl Perl và thêm cú pháp mở rộng vào cú pháp mở rộng Perl. Nếu nhân vật đầu tiên sau dấu hỏi là một

String 1: 'a\t'
String 2: 'a\t' 
91, bạn sẽ biết rằng nó là một phần mở rộng mà đặc trưng cho Python.

Bây giờ chúng tôi đã xem xét cú pháp mở rộng chung, chúng tôi có thể quay lại các tính năng đơn giản hóa việc làm việc với các nhóm trong Res phức tạp.

Đôi khi, bạn sẽ muốn sử dụng một nhóm để biểu thị một phần của biểu thức thông thường, nhưng aren quan tâm đến việc truy xuất nội dung của nhóm. Bạn có thể làm rõ thực tế này bằng cách sử dụng một nhóm không bắt giữ:

String 1: 'a\t'
String 2: 'a\t' 
92, trong đó bạn có thể thay thế
String 1: 'a\t'
String 2: 'a\t' 
93 bằng bất kỳ biểu thức thông thường nào khác.

String 1: 'a\t'
String 2: 'a\t' 
3

Ngoại trừ thực tế là bạn có thể lấy lại nội dung của những gì nhóm phù hợp, một nhóm không bắt giữ hoạt động giống hệt như một nhóm bắt giữ; Bạn có thể đặt bất cứ thứ gì bên trong nó, lặp lại nó với một metacharacter lặp lại như

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
11 và làm tổ nó trong các nhóm khác (bắt hoặc không bắt).
String 1: 'a\t'
String 2: 'a\t' 
92 đặc biệt hữu ích khi sửa đổi một mẫu hiện có, vì bạn có thể thêm các nhóm mới mà không thay đổi cách tất cả các nhóm khác được đánh số. Cần phải đề cập rằng không có sự khác biệt về hiệu suất trong việc tìm kiếm giữa các nhóm bắt giữ và không bắt giữ; Không hình thức nào nhanh hơn hình thức khác.

Một tính năng quan trọng hơn được đặt tên là các nhóm: thay vì đề cập đến chúng theo số, các nhóm có thể được tham chiếu bằng một tên.

Cú pháp cho một nhóm được đặt tên là một trong những tiện ích mở rộng cụ thể của Python:

String 1: 'a\t'
String 2: 'a\t' 
96. Tên là, rõ ràng, tên của nhóm. Các nhóm được đặt tên hoạt động chính xác giống như bắt giữ các nhóm, và cũng liên kết một tên với một nhóm. Các phương thức đối tượng khớp liên quan đến việc thu thập các nhóm đều chấp nhận các số nguyên đề cập đến nhóm theo số hoặc các chuỗi có chứa tên nhóm mong muốn. Các nhóm được đặt tên vẫn được đưa ra các số, vì vậy bạn có thể truy xuất thông tin về một nhóm theo hai cách:match object methods that deal with capturing groups all accept either integers that refer to the group by number or strings that contain the desired group’s name. Named groups are still given numbers, so you can retrieve information about a group in two ways:

String 1: 'a\t'
String 2: 'a\t' 
4

Ngoài ra, bạn có thể truy xuất các nhóm được đặt tên là từ điển với

String 1: 'a\t'
String 2: 'a\t' 
97:

String 1: 'a\t'
String 2: 'a\t' 
5

Các nhóm được đặt tên là tiện dụng vì họ cho phép bạn sử dụng tên dễ nhớ, thay vì phải nhớ số. Ở đây, một ví dụ RE từ mô -đun

String 1: 'a\t'
String 2: 'a\t' 
98:

String 1: 'a\t'
String 2: 'a\t' 
6

Nó rõ ràng dễ dàng hơn nhiều để lấy

String 1: 'a\t'
String 2: 'a\t' 
99, thay vì phải nhớ lấy lại nhóm 9.

Cú pháp cho các bản sao lưu trong một biểu thức như

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
00 đề cập đến số lượng của nhóm. Có một cách tự nhiên một biến thể sử dụng tên nhóm thay vì số. Đây là một phần mở rộng Python khác:
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
01 chỉ ra rằng nội dung của nhóm được gọi là tên một lần nữa phải được khớp tại điểm hiện tại. Biểu thức chính quy để tìm từ nhân đôi,
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
02 cũng có thể được viết là
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
03:

String 1: 'a\t'
String 2: 'a\t' 
7

Asserments LookAhead

Một khẳng định không có chiều rộng khác là khẳng định lookahead. Các khẳng định lookahead có sẵn ở cả hình thức tích cực và tiêu cực, và trông như thế này:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
04

Khẳng định nhìn tích cực. Điều này thành công nếu biểu thức có chứa chính quy, được biểu thị ở đây bằng

String 1: 'a\t'
String 2: 'a\t' 
93, phù hợp thành công tại vị trí hiện tại và không thành công. Nhưng, một khi biểu thức chứa đã được thử, động cơ phù hợp không tiến lên; Phần còn lại của mẫu được thử ngay khi xác nhận bắt đầu.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
06

Khẳng định cái nhìn tiêu cực. Đây là điều ngược lại với khẳng định tích cực; Nó thành công nếu biểu thức chứa không phù hợp ở vị trí hiện tại trong chuỗi.

Để làm cho bê tông này, hãy để Lôi nhìn vào một trường hợp mà một cái nhìn là hữu ích. Hãy xem xét một mẫu đơn giản để khớp với tên tệp và chia nó thành một tên cơ sở và một phần mở rộng, được phân tách bằng

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
08. Ví dụ, trong
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
08,
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
09 là tên cơ sở và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
10 là tiện ích mở rộng tên tệp.

Mô hình phù hợp với điều này khá đơn giản:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
11

Lưu ý rằng

>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
08 cần được đối xử đặc biệt bởi vì nó là một metacharacter, do đó, nó bên trong một lớp nhân vật chỉ phù hợp với nhân vật cụ thể đó. Cũng nhận thấy dấu vết
>>> match = re.search('a\\t','a\\t')        //Match is None
73; Điều này được thêm vào để đảm bảo rằng tất cả phần còn lại của chuỗi phải được bao gồm trong phần mở rộng. Biểu thức chính quy này phù hợp với
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
14 và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
15 và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
16 và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
17.

Bây giờ, hãy xem xét làm phức tạp vấn đề một chút; Điều gì sẽ xảy ra nếu bạn muốn khớp tên tệp trong đó tiện ích mở rộng không phải là

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18? Một số nỗ lực không chính xác:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
19 Nỗ lực đầu tiên ở trên cố gắng loại trừ
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18 bằng cách yêu cầu ký tự đầu tiên của phần mở rộng không phải là
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4. Điều này là sai, bởi vì mẫu cũng không phù hợp với
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
14.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
23

Biểu thức trở nên lộn xộn hơn khi bạn cố gắng vá giải pháp đầu tiên bằng cách yêu cầu một trong các trường hợp sau để khớp: ký tự đầu tiên của phần mở rộng isn

>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
4; Nhân vật thứ hai là
>>> match = re.search(r'a\\t','a\\t')           // match contains 'a\t'
3; Hoặc nhân vật thứ ba là
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
26. Điều này chấp nhận
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
14 và từ chối
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
15, nhưng nó đòi hỏi một phần mở rộng ba chữ cái và won đã chấp nhận một tên tệp với phần mở rộng hai chữ cái như
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
16. Chúng tôi sẽ làm phức tạp mô hình một lần nữa trong một nỗ lực để sửa chữa nó.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
30

Trong lần thử thứ ba, các chữ cái thứ hai và thứ ba đều được thực hiện tùy chọn để cho phép các phần mở rộng phù hợp ngắn hơn ba ký tự, chẳng hạn như

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
16.

Các mẫu mà trở nên thực sự phức tạp bây giờ, khiến nó khó đọc và hiểu. Tồi tệ hơn, nếu vấn đề thay đổi và bạn muốn loại trừ cả

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18 và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
33 dưới dạng các phần mở rộng, mẫu sẽ còn phức tạp và khó hiểu hơn nữa.

Một cái nhìn tiêu cực cắt giảm tất cả sự nhầm lẫn này:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
34 LOẠI ĐÁNH GIÁ có nghĩa là: Nếu biểu thức
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18 không phù hợp tại thời điểm này, hãy thử phần còn lại của mẫu; Nếu
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
36 không khớp, toàn bộ mẫu sẽ thất bại. Trailing
>>> match = re.search('a\\t','a\\t')        //Match is None
73 được yêu cầu để đảm bảo rằng một cái gì đó như
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
38, trong đó phần mở rộng chỉ bắt đầu với
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18, sẽ được cho phép.
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
40 đảm bảo rằng mẫu hoạt động khi có nhiều dấu chấm trong tên tệp.

Không bao gồm một phần mở rộng tên tệp khác bây giờ là dễ dàng; Đơn giản chỉ cần thêm nó như một sự thay thế bên trong khẳng định. Mẫu sau đây loại trừ tên tệp kết thúc trong

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
18 hoặc
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
33:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
43

Sửa đổi chuỗi

Cho đến thời điểm này, chúng tôi chỉ đơn giản thực hiện các tìm kiếm đối với một chuỗi tĩnh. Các biểu thức thông thường cũng thường được sử dụng để sửa đổi các chuỗi theo nhiều cách khác nhau, sử dụng các phương thức mẫu sau:

Method/Attribute

Mục đích

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
44

Chia chuỗi thành một danh sách, chia nó ở bất cứ nơi nào RE khớp với

>>> match = re.search('a\\t','a\\t')        //Match is None
47

Tìm tất cả các chuỗi con trong đó RE khớp và thay thế chúng bằng một chuỗi khác

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
46

Làm điều tương tự như

>>> match = re.search('a\\t','a\\t')        //Match is None
47, nhưng trả về chuỗi mới và số lượng thay thế

Chuỗi phân tách

Phương pháp

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
44 của một mẫu phân tách một chuỗi cách nhau bất cứ nơi nào khớp nối lại, trả lại một danh sách các mảnh. Nó tương tự như phương pháp
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
44 của chuỗi nhưng cung cấp nhiều tính tổng quát hơn trong các dấu phân cách mà bạn có thể chia bằng; Chuỗi
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
44 chỉ hỗ trợ chia tách bằng khoảng trắng hoặc bằng một chuỗi cố định. Như bạn đã mong đợi, cũng có một hàm
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
51 ở cấp độ mô-đun.

.Split (Chuỗi [, MaxSplit = 0])split(string[, maxsplit=0])

Chia chuỗi phân chia theo các kết quả của biểu thức chính quy. Nếu chụp dấu ngoặc đơn được sử dụng trong RE, thì nội dung của chúng cũng sẽ được trả lại như một phần của danh sách kết quả. Nếu MAXSplit là khác nhau, tại hầu hết các phân tách MaxSplit được thực hiện.

Bạn có thể giới hạn số lượng phân tách được thực hiện, bằng cách chuyển một giá trị cho MaxSplit. Khi MAXSplit là không khác biệt, tại hầu hết các phân tách MaxSplit sẽ được thực hiện và phần còn lại của chuỗi được trả về làm yếu tố cuối cùng của danh sách. Trong ví dụ sau, dấu phân cách là bất kỳ chuỗi các ký tự không phải là vô hiệu.

String 1: 'a\t'
String 2: 'a\t' 
8

Đôi khi, bạn không chỉ quan tâm đến văn bản giữa các phân định là gì, mà còn cần biết dấu phân cách là gì. Nếu thu được dấu ngoặc đơn được sử dụng trong RE, thì các giá trị của chúng cũng được trả về như một phần của danh sách. So sánh các cuộc gọi sau:

String 1: 'a\t'
String 2: 'a\t' 
9

Hàm cấp độ mô-đun

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
51 thêm RE được sử dụng làm đối số đầu tiên, nhưng nếu không thì giống nhau.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
0

Tìm kiếm và thay thế Or

Một nhiệm vụ phổ biến khác là tìm tất cả các trận đấu cho một mẫu và thay thế chúng bằng một chuỗi khác. Phương thức

>>> match = re.search('a\\t','a\\t')        //Match is None
47 có giá trị thay thế, có thể là một chuỗi hoặc hàm và chuỗi được xử lý.

.sub (thay thế, chuỗi [, đếm = 0])sub(replacement, string[, count=0])

Trả về chuỗi thu được bằng cách thay thế các lần xuất hiện không chồng chéo bên trái của RE trong chuỗi bằng cách thay thế thay thế. Nếu mẫu được tìm thấy, chuỗi được trả về không thay đổi.

Số lượng đối số tùy chọn là số lượng tối đa của các lần xuất hiện mẫu được thay thế; Đếm phải là một số nguyên không âm. Giá trị mặc định của 0 có nghĩa là thay thế tất cả các lần xuất hiện.

Ở đây, một ví dụ đơn giản về việc sử dụng phương pháp

>>> match = re.search('a\\t','a\\t')        //Match is None
47. Nó thay thế tên màu bằng từ
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
55:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
1

Phương thức

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
46 thực hiện cùng một công việc, nhưng trả về 2-tuple chứa giá trị chuỗi mới và số lượng thay thế được thực hiện:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
2

Các trận đấu trống chỉ được thay thế khi họ không liền kề với trận đấu trống trước đó.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
3

Nếu thay thế là một chuỗi, bất kỳ dấu gạch chéo ngược nào đều thoát trong đó được xử lý. Đó là,

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
57 được chuyển đổi thành một ký tự mới,
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
58 được chuyển đổi thành một trở lại vận chuyển, v.v. Những trốn thoát chưa biết như
String 1: 'a\t'
String 2: 'a\t' 
82 bị bỏ lại một mình. Các bản sao lưu, chẳng hạn như
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
60, được thay thế bằng chuỗi con phù hợp với nhóm tương ứng trong RE. Điều này cho phép bạn kết hợp các phần của văn bản gốc trong chuỗi thay thế kết quả.

Ví dụ này khớp với từ

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
61 theo sau là một chuỗi được đặt trong
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
62,
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
63 và thay đổi
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
61 thành
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
65:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
4

Ngoài ra, còn có một cú pháp để đề cập đến các nhóm được đặt tên theo định nghĩa của cú pháp

String 1: 'a\t'
String 2: 'a\t' 
96.
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
67 sẽ sử dụng chuỗi con được khớp bởi nhóm có tên
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
68 và
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
69 sử dụng số nhóm tương ứng. Do đó,
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
70 tương đương với
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
71, nhưng không phải là mơ hồ trong một chuỗi thay thế như
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
72. .

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
5

Thay thế cũng có thể là một chức năng, giúp bạn kiểm soát nhiều hơn. Nếu thay thế là một hàm, hàm được gọi cho mọi lần xuất hiện không chồng chéo của mẫu. Trên mỗi cuộc gọi, hàm được chuyển một đối số đối tượng khớp cho trận đấu và có thể sử dụng thông tin này để tính toán chuỗi thay thế mong muốn và trả về nó.match object argument for the match and can use this information to compute the desired replacement string and return it.

Trong ví dụ sau, hàm thay thế chuyển số thập phân thành thập lục phân:

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
6

Khi sử dụng hàm

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
75 cấp độ mô-đun, mẫu được truyền làm đối số đầu tiên. Mẫu có thể được cung cấp dưới dạng đối tượng hoặc dưới dạng chuỗi; Nếu bạn cần chỉ định các cờ biểu thức thông thường, bạn phải sử dụng một đối tượng mẫu làm tham số đầu tiên hoặc sử dụng các bộ sửa đổi nhúng trong chuỗi mẫu, ví dụ:
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
76 Trả về
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
77.

Những vấn đề chung¶

Biểu thức chính quy là một công cụ mạnh mẽ cho một số ứng dụng, nhưng trong một số cách, hành vi của họ không trực quan và đôi khi họ không hành xử theo cách bạn có thể mong đợi. Phần này sẽ chỉ ra một số cạm bẫy phổ biến nhất.

Sử dụng các phương thức chuỗi

Đôi khi sử dụng mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3 là một sai lầm. Nếu bạn phù hợp với một chuỗi cố định hoặc một lớp ký tự duy nhất và bạn không sử dụng bất kỳ tính năng
String 1: 'a\\t'
String 2: 'a\t'
3 nào như cờ
>>> match = re.search('a\\t','a\\t')        //Match is None
50, thì có thể không cần phải có toàn bộ sức mạnh của các biểu thức thông thường. Các chuỗi có một số phương pháp để thực hiện các hoạt động với các chuỗi cố định và chúng thường nhanh hơn nhiều, bởi vì việc triển khai là một vòng C nhỏ duy nhất mà Lọ được tối ưu hóa cho mục đích, thay vì động cơ biểu thức chính quy lớn hơn, tổng quát hơn.

Một ví dụ có thể là thay thế một chuỗi cố định bằng một chuỗi khác; Ví dụ: bạn có thể thay thế

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
81 bằng
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
82.
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
75 có vẻ như là chức năng sử dụng cho việc này, nhưng hãy xem xét phương pháp
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
84. Lưu ý rằng
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
84 cũng sẽ thay thế
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
81 Các từ bên trong, biến
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
87 thành
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
88, nhưng bản re ngây thơ
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
81 cũng sẽ làm điều đó. .

Một nhiệm vụ phổ biến khác là xóa mọi lần xuất hiện của một ký tự từ một chuỗi hoặc thay thế nó bằng một ký tự đơn khác. Bạn có thể làm điều này với một cái gì đó như

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
93, nhưng
>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
94 có khả năng thực hiện cả hai nhiệm vụ và sẽ nhanh hơn bất kỳ hoạt động biểu thức chính quy nào có thể.

Nói tóm lại, trước khi chuyển sang mô -đun

String 1: 'a\\t'
String 2: 'a\t'
3, hãy xem xét liệu vấn đề của bạn có thể được giải quyết bằng phương pháp chuỗi nhanh hơn và đơn giản hơn hay không.

khớp () so với tìm kiếm () ¶

Hàm

>>> match = re.search('a\\t','a\\t')        //Match is None
07 chỉ kiểm tra xem RE có khớp ở đầu chuỗi trong khi
>>> match = re.search('a\\t','a\\t')        //Match is None
08 sẽ quét về phía trước qua chuỗi cho một trận đấu không. Nó rất quan trọng để ghi nhớ sự khác biệt này. Hãy nhớ rằng,
>>> match = re.search('a\\t','a\\t')        //Match is None
07 sẽ chỉ báo cáo một trận đấu thành công sẽ bắt đầu ở 0; Nếu trận đấu sẽ bắt đầu ở 0,
>>> match = re.search('a\\t','a\\t')        //Match is None
07 sẽ không báo cáo.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
7

Mặt khác,

>>> match = re.search('a\\t','a\\t')        //Match is None
08 sẽ quét về phía trước qua chuỗi, báo cáo trận đấu đầu tiên mà nó tìm thấy.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
8

Đôi khi, bạn sẽ bị cám dỗ để tiếp tục sử dụng

String 1: 'a\\t'
String 2: 'a\t'
01 và chỉ cần thêm
String 1: 'a\\t'
String 2: 'a\t'
02 vào mặt trước của RE. Thay vào đó, hãy chống lại sự cám dỗ này và sử dụng
String 1: 'a\\t'
String 2: 'a\t'
03. Trình biên dịch biểu thức chính quy thực hiện một số phân tích RES để tăng tốc quá trình tìm kiếm một trận đấu. Một phân tích như vậy đưa ra những gì nhân vật đầu tiên của một trận đấu phải là gì; Ví dụ: một mẫu bắt đầu bằng
String 1: 'a\\t'
String 2: 'a\t'
04 phải khớp với bắt đầu với
String 1: 'a\\t'
String 2: 'a\t'
05. Phân tích cho phép động cơ nhanh chóng quét qua chuỗi tìm kiếm ký tự bắt đầu, chỉ thử toàn bộ trận đấu nếu tìm thấy
String 1: 'a\\t'
String 2: 'a\t'
05.

Thêm

String 1: 'a\\t'
String 2: 'a\t'
02 đánh bại tối ưu hóa này, yêu cầu quét vào cuối chuỗi và sau đó quay lại để tìm một trận đấu cho phần còn lại của RE. Sử dụng
String 1: 'a\\t'
String 2: 'a\t'
03 thay thế.

Tham lam so với không tham lam

Khi lặp lại một biểu thức chính quy, như trong

String 1: 'a\\t'
String 2: 'a\t'
09, hành động kết quả là tiêu thụ càng nhiều mô hình càng tốt. Thực tế này thường cắn bạn khi bạn đang cố gắng phù hợp với một cặp phân tích cân bằng, chẳng hạn như giá đỡ góc xung quanh thẻ HTML. Mẫu ngây thơ để phù hợp với một thẻ HTML duy nhất không hoạt động vì tính chất tham lam của
String 1: 'a\\t'
String 2: 'a\t'
02.

>>> match = re.search('a\\\\t','a\\t')          // Match contains 'a\t'
9

RE khớp với

String 1: 'a\\t'
String 2: 'a\t'
11 trong
String 1: 'a\\t'
String 2: 'a\t'
12 và
String 1: 'a\\t'
String 2: 'a\t'
02 tiêu thụ phần còn lại của chuỗi. Mặc dù vậy, vẫn còn nhiều hơn nữa trong RE, và
String 1: 'a\\t'
String 2: 'a\t'
14 có thể phù hợp ở cuối chuỗi, do đó, công cụ biểu thức thông thường phải quay lại ký tự cho đến khi nó tìm thấy một trận đấu cho
String 1: 'a\\t'
String 2: 'a\t'
14. Trận đấu cuối cùng kéo dài từ
String 1: 'a\\t'
String 2: 'a\t'
11 trong
String 1: 'a\\t'
String 2: 'a\t'
12 đến
String 1: 'a\\t'
String 2: 'a\t'
18 trong
String 1: 'a\\t'
String 2: 'a\t'
19, đó là những gì bạn muốn.

Trong trường hợp này, giải pháp là sử dụng các bộ định lượng không màu xanh lá cây

String 1: 'a\\t'
String 2: 'a\t'
20,
String 1: 'a\\t'
String 2: 'a\t'
21,
String 1: 'a\\t'
String 2: 'a\t'
22 hoặc
String 1: 'a\\t'
String 2: 'a\t'
23, phù hợp với văn bản ít nhất có thể. Trong ví dụ trên,
String 1: 'a\\t'
String 2: 'a\t'
18 được thử ngay sau khi
String 1: 'a\\t'
String 2: 'a\t'
11 đầu tiên kết hợp và khi nó bị hỏng, động cơ sẽ tiến một nhân vật tại một thời điểm, thử lại
String 1: 'a\\t'
String 2: 'a\t'
18 ở mỗi bước. Điều này chỉ tạo ra kết quả đúng:

String 1: 'a\\t'
String 2: 'a\t'
0

. Xử lý tất cả các trường hợp có thể, các mẫu sẽ rất phức tạp. Sử dụng mô -đun phân tích cú pháp HTML hoặc XML cho các tác vụ đó.)

Sử dụng Re.verbose¶

Đến bây giờ, bạn có thể nhận thấy rằng các biểu thức thông thường là một ký hiệu rất nhỏ gọn, nhưng chúng không thể đọc được khủng khiếp. Res của sự phức tạp vừa phải có thể trở thành các bộ sưu tập dài các dấu gạch chéo ngược, dấu ngoặc đơn và metacharacters, khiến chúng khó đọc và hiểu.

Đối với độ phân giải như vậy, việc chỉ định cờ

>>> match = re.search('a\\t','a\\t')        //Match is None
52 khi biên dịch biểu thức thông thường có thể hữu ích, bởi vì nó cho phép bạn định dạng biểu thức thông thường rõ ràng hơn.

Cờ

>>> match = re.search('a\\t','a\\t')        //Match is None
52 có một số hiệu ứng. Whitespace trong biểu thức chính quy không phải là bên trong một lớp nhân vật bị bỏ qua. Điều này có nghĩa là một biểu thức như
String 1: 'a\\t'
String 2: 'a\t'
29 tương đương với
String 1: 'a\\t'
String 2: 'a\t'
30 không thể đọc được, nhưng
String 1: 'a\\t'
String 2: 'a\t'
31 vẫn sẽ khớp với các ký tự
String 1: 'a\\t'
String 2: 'a\t'
0,
>>> s = '\\t'
>>> print ("[" + s  + "]")
>>> [\t]                // '\t' after preprocessing
25 hoặc một không gian. Ngoài ra, bạn cũng có thể đặt nhận xét bên trong một RE; Nhận xét mở rộng từ một ký tự
String 1: 'a\\t'
String 2: 'a\t'
34 sang dòng mới tiếp theo. Khi được sử dụng với các chuỗi được trích xuất ba, điều này cho phép RES được định dạng gọn gàng hơn:

String 1: 'a\\t'
String 2: 'a\t'
1

Điều này dễ đọc hơn nhiều so với:

String 1: 'a\\t'
String 2: 'a\t'
2

Nhận xét¶

Biểu thức thường xuyên là một chủ đề phức tạp. Tài liệu này có giúp bạn hiểu chúng không? Có những phần không rõ ràng, hoặc những vấn đề bạn gặp phải mà người sói được bao phủ ở đây? Nếu vậy, xin vui lòng gửi đề xuất để cải thiện cho tác giả.

Cuốn sách hoàn chỉnh nhất về các cách diễn đạt thường xuyên là gần như chắc chắn là Jeffrey Friedl, làm chủ các biểu thức thông thường, được xuất bản bởi O hèReilly. Thật không may, nó chỉ tập trung vào hương vị Perl và Java, của các biểu thức thông thường, và không chứa bất kỳ tài liệu Python nào, vì vậy nó đã giành được hữu ích như một tài liệu tham khảo cho lập trình trong Python. (Phiên bản đầu tiên bao gồm mô-đun

String 1: 'a\\t'
String 2: 'a\t'
35 đã được loại bỏ, đã giành được giúp bạn rất nhiều.) Hãy xem xét kiểm tra nó từ thư viện của bạn.

\\ có nghĩa là gì trong regex?

\\.phù hợp với nhân vật theo nghĩa đen..Backslash đầu tiên được hiểu là một ký tự thoát của đầu đọc chuỗi Emacs, kết hợp với dấu gạch chéo ngược thứ hai, chèn một ký tự dấu gạch chéo ngược theo nghĩa đen vào chuỗi đang được đọc.Công cụ biểu thức chính quy nhận chuỗi \.html? \ '.matches the literal character . . the first backslash is interpreted as an escape character by the Emacs string reader, which combined with the second backslash, inserts a literal backslash character into the string being read. the regular expression engine receives the string \. html?\ ' .

Backslash có phải là một nhân vật đặc biệt trong Regex không?

Đó là bởi vì dấu gạch chéo ngược cũng là một nhân vật đặc biệt.Backslash kết hợp với một ký tự theo nghĩa đen có thể tạo mã thông báo regex với ý nghĩa đặc biệt.Ví dụ.\ d là một tốc ký phù hợp với một chữ số từ 0 đến 9. Thoát khỏi một metacharacter duy nhất với một dấu gạch chéo ngược hoạt động trong tất cả các hương vị biểu thức thông thường.the backslash is also a special character. The backslash in combination with a literal character can create a regex token with a special meaning. E.g. \d is a shorthand that matches a single digit from 0 to 9. Escaping a single metacharacter with a backslash works in all regular expression flavors.