Thoát chuỗi regex trong Python


229

Tôi muốn sử dụng đầu vào từ người dùng làm mẫu biểu thức chính quy cho tìm kiếm trên một số văn bản. Nó hoạt động, nhưng làm thế nào tôi có thể xử lý các trường hợp người dùng đặt các ký tự có ý nghĩa trong regex? Ví dụ: người dùng muốn tìm kiếm Word (s): regex engine sẽ lấy (s)nhóm làm nhóm. Tôi muốn nó coi nó như một chuỗi "(s)". Tôi có thể chạy replacetrên đầu vào của người dùng và thay thế (bằng \()với \)nhưng vấn đề là tôi sẽ cần phải thay thế cho mọi biểu tượng regex có thể. Bạn có biết một số cách tốt hơn?

Câu trả lời:


324

Sử dụng re.escape()chức năng này:

4.2.3 reNội dung mô-đun

thoát (chuỗi)

Trả về chuỗi với tất cả các chữ số không được viết ngược; điều này rất hữu ích nếu bạn muốn khớp một chuỗi ký tự tùy ý có thể có các siêu ký tự biểu thức chính quy trong đó.

Một ví dụ đơn giản, tìm kiếm bất kỳ sự xuất hiện nào của chuỗi được cung cấp tùy ý theo sau 's' và trả về đối tượng khớp.

def simplistic_plural(word, text):
    word_or_plural = re.escape(word) + 's?'
    return re.match(word_or_plural, text)

53

Bạn có thể sử dụng re.escape () :

re.escape (chuỗi) Trả về chuỗi với tất cả các chữ số không được viết ngược; điều này rất hữu ích nếu bạn muốn khớp một chuỗi ký tự tùy ý có thể có các siêu ký tự biểu thức chính quy trong đó.

>>> import re
>>> re.escape('^a.*$')
'\\^a\\.\\*\\$'

3

Thật không may, re.escape()không phù hợp với chuỗi thay thế:

>>> re.sub('a', re.escape('_'), 'aa')
'\\_\\_'

Một giải pháp là đặt sự thay thế trong lambda:

>>> re.sub('a', lambda _: '_', 'aa')
'__'

bởi vì giá trị trả về của lambda được coi re.sub()là một chuỗi ký tự.


3
Đối replsố re.sublà một chuỗi, không phải là biểu thức chính quy; áp dụng re.escapecho nó không có ý nghĩa gì ở nơi đầu tiên.
tripleee

5
@tripleee Điều đó không chính xác, replđối số không phải là một chuỗi đơn giản, nó được phân tích cú pháp. Chẳng hạn, re.sub(r'(.)', r'\1', 'X')sẽ trở lại X, không \1.
Flimm

4
Đây là câu hỏi có liên quan để thoát khỏi replđối số: stackoverflow.com/q/49943270/247696
Flimm

3
Thay đổi trong phiên bản 3.3: Ký tự '_' không còn được thoát. Thay đổi trong phiên bản 3.7: Chỉ các ký tự có thể có ý nghĩa đặc biệt trong biểu thức chính quy mới được thoát. (Tại sao nó lại mất nhiều thời gian như vậy?)
Cees Timmerman

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.