Tôi cảm thấy những ví dụ này với sự phức tạp ngày càng tăng là thú vị:
ppt = 'abc HERE abc'
ept = 'abc TERM abc'
re_ppt = ppt.replace['HERE', '[.+]']
print[]
print[f'{re_ppt=}']
out = re.search[pattern=re_ppt, string=ept]
print[out]
print[out.groups[]]
ppt = 'abc HERE abc HERE abc'
ept = 'abc TERM1 abc TERM2 abc'
re_ppt = ppt.replace['HERE', '[.+]']
print[]
print[f'{re_ppt=}']
out = re.search[pattern=re_ppt, string=ept]
print[out]
print[out.groups[]]
print[]
ppt = """[fun n : nat =>
nat_ind [fun n0 : nat => n0 + 0 = n0] ?Goal"""
print[f"{ppt=}"]
ept = """[fun n : nat =>
nat_ind [fun n0 : nat => n0 + 0 = n0] [eq_refl : 0 + 0 = 0]"""
print[f'{ept=}']
pattern_meta_var = r'\?[\w]+'
_ppt = re.sub[pattern=pattern_meta_var, repl='HERE', string=ppt]
print[f'{ppt=}']
_ppt = re.escape[_ppt]
print[f'{ppt=}']
re_ppt = _ppt.replace['HERE', '[.+]']
print[f'{re_ppt=}']
out = re.search[pattern=re_ppt, string=ept]
print[out]
print[out.groups[]]
print[]
# sometimes the actual proof term missing won't have white spaces surrounding it but the ppt will have surrounding spaces where the hole
# would be. So in goal cames I removed the surrounding whitespaces. Then inserted a regex that accepts a hole with or
# without surrounding white spaces. That way in case the proof term in the hole does have surrounding white spaces then
# the regex hole catcher would match it anyway.
ppt = """\n [fun [n' : nat] [IH : n' + 0 = n'] => ?Goal0] n]"""
ept = """\n [fun [n' : nat] [IH : n' + 0 = n'] =>\n\teq_ind_r [fun n0 : nat => S n0 = S n'] eq_refl IH : S n' + 0 = S n'] n]"""
print[f"{ppt=}"]
print[f'{ept=}']
pattern_meta_var = r'\s*\?[\w]+\s*'
_ppt = re.sub[pattern=pattern_meta_var, repl='HERE', string=ppt]
print[f'{_ppt=}']
_ppt = re.escape[_ppt]
print[f'{_ppt=}']
re_ppt = _ppt.replace['HERE', '\s*[.+]\s*']
print[f'{re_ppt=}']
out = re.search[pattern=re_ppt, string=ept]
print[out]
assert out is not None, f'expected two holes matched but go {out=}'
print[out.groups[]]
print[]
ppt = """[fun n : nat =>
nat_ind [fun n0 : nat => n0 + 0 = n0] ?Goal
[fun [n' : nat] [IH : n' + 0 = n'] => ?Goal0] n]"""
print[f"{ppt=}"]
ept = """[fun n : nat =>
nat_ind [fun n0 : nat => n0 + 0 = n0] [eq_refl : 0 + 0 = 0]
[fun [n' : nat] [IH : n' + 0 = n'] =>
eq_ind_r [fun n0 : nat => S n0 = S n'] eq_refl IH : S n' + 0 = S n'] n]"""
print[f'{ept=}']
pattern_meta_var = r'\s*\?[\w]+\s*'
_ppt = re.sub[pattern=pattern_meta_var, repl='HERE', string=ppt]
print[f'{_ppt=}']
_ppt = re.escape[_ppt]
print[f'{_ppt=}']
re_ppt = _ppt.replace['HERE', '\s*[.+]\s*']
print[f'{re_ppt=}']
out = re.search[pattern=re_ppt, string=ept]
print[out]
print[out.groups[]]
Để phù hợp với bất kỳ văn bản nào giữa hai chuỗi/mẫu với biểu thức thông thường trong Python bạn có thể sử dụng:text between two strings/patterns with a regular expression in Python you can use:
re.search[r'pattern1[.*?]pattern2', s].group[1]
Trong các phần tiếp theo, bạn sẽ thấy cách áp dụng trên bằng cách sử dụng một ví dụ đơn giản.
Trong ví dụ này, chúng tôi đang sử dụng bộ dữ liệu Kaggle. Nếu bạn muốn tìm hiểu thêm về cách đọc Kaggle dưới dạng dữ liệu gấu trúc, hãy kiểm tra bài viết này: Cách tìm kiếm và tải xuống bộ dữ liệu Kaggle xuống Pandas DataFrame
Để bắt đầu với một ví dụ đơn giản, hãy để có một văn bản tiếp theo:
Bước 1 Một số văn bản Bước 2 Thêm văn bản Bước 3 sau đó thêm văn bản
Và chúng tôi muốn trích xuất mọi thứ giữa
re.search[r'pattern1[.*?]pattern2', s].group[1]
1 và re.search[r'pattern1[.*?]pattern2', s].group[1]
2. Để làm như vậy, chúng tôi sẽ sử dụng nhóm Capture như:import re
s = 'step 1 some text step 2 more text step 3 then more text'
re.search[r'step 1[.*?]step 2', s].group[1]
result:
' some text '
Làm thế nào nó hoạt động:
1 - Phù hợp với các ký tự Bước 1 theo nghĩa đen [trường hợp nhạy cảm]step 1 literally [case sensitive]re.search[r'pattern1[.*?]pattern2', s].group[1]
4 - Phù hợp với bất kỳ ký tự nào giữa thời gian bằng không và không giới hạn mở rộng khi cần thiết [lười biếng]re.search[r'pattern1[.*?]pattern2', s].group[1]
2 - Phù hợp với các ký tự Bước 2 theo nghĩa đen [trường hợp nhạy cảm]step 2 literally [case sensitive]re.search[r'pattern1[.*?]pattern2', s].group[1]
Tìm kiếm không lười biếng
Ví dụ trước sẽ dừng lại cho đến khi nó tìm thấy văn bản thỏa mãn nó. Nếu bạn thích trích xuất:
some text step 2 more text
Sau đó, bạn cần thay đổi tìm kiếm thành:
re.findall[r'step \d [.*] step \d', s]
Bước 2: Kết hợp văn bản giữa hai mẫu
Bây giờ chúng ta hãy nói rằng bạn muốn khớp với một mẫu và không cố định văn bản. Trong ví dụ này, chúng ta sẽ thấy cách trích xuất
re.search[r'pattern1[.*?]pattern2', s].group[1]
6 theo sau là một chữ số:to
match a pattern and not fixed text. In this example we will see how to extract re.search[r'pattern1[.*?]pattern2', s].group[1]
6 followed by a digit:import re
s = 'step 1 some text\nstep 2 more text\nstep 3 then more text\nconclusion'
re.findall[r'[?:step \d][.*?][?:\n]', s]
Vì vậy, có văn bản tiếp theo:
step 1 some text
step 2 more text
step 3 then more text
conclusion
Chúng tôi sẽ trích xuất:
[' some text', ' more text', ' then more text']
Làm thế nào nó hoạt động?
7 - Nhóm không bắt giữ -re.search[r'pattern1[.*?]pattern2', s].group[1]
8 - Nó sẽ được khớp nhưng không được trích xuấtre.search[r'pattern1[.*?]pattern2', s].group[1]
9 - Phù hợp với các ký tự theo nghĩa đen [trường hợp nhạy cảm] theo sau là một chữ số [tương đương với [0-9]]step literally [case sensitive] followed by a digit [equivalent to [0-9]]re.search[r'pattern1[.*?]pattern2', s].group[1]
4 - Nhóm chụp thứ nhất - Chụp bất cứ thứ gì lười biếngre.search[r'pattern1[.*?]pattern2', s].group[1]
1 - Nhóm không bắt giữimport re s = 'step 1 some text step 2 more text step 3 then more text' re.search[r'step 1[.*?]step 2', s].group[1]
2 khớp với ký tự dòng mớiimport re s = 'step 1 some text step 2 more text step 3 then more text' re.search[r'step 1[.*?]step 2', s].group[1]
Bước 3: Kết hợp văn bản giữa hai mẫu lười biếng so với tham lam
Trong bước này, chúng tôi sẽ đưa ra một lời giải thích hơn cho trận đấu lười biếng vs tham lam. Sự khác biệt có thể được giải thích như:lazy vs greedy match. The difference can be explained as:
3 - lười biếngLazyimport re s = 'step 1 some text step 2 more text step 3 then more text' re.search[r'step 1[.*?]step 2', s].group[1]
4 - tham lamGreedyimport re s = 'step 1 some text step 2 more text step 3 then more text' re.search[r'step 1[.*?]step 2', s].group[1]
Vì vậy, hãy nói rằng chúng tôi có một danh sách các thư như:
| [Email & nbsp; được bảo vệ]; | [Email & nbsp; được bảo vệ]; | [Email & nbsp; được bảo vệ];
Nếu chúng ta thực hiện trích xuất tham lam giữa các chuỗi, chúng ta sẽ nhận được:greedy extraction between to strings we will get:
s = "|[email protected]; |[email protected];|[email protected];"
re.findall[r'\|[.*];', s]
Kết quả sẽ chỉ là 1 trận đấu từ
import re
s = 'step 1 some text step 2 more text step 3 then more text'
re.search[r'step 1[.*?]step 2', s].group[1]
5 đầu tiên đến lần cuối import re
s = 'step 1 some text step 2 more text step 3 then more text'
re.search[r'step 1[.*?]step 2', s].group[1]
6:['[Email & nbsp; được bảo vệ]; | [Email & nbsp; được bảo vệ]; | [Email & nbsp; được bảo vệ] ']]
Trong khi nếu chúng ta thực hiện tìm kiếm lười biếng cho một văn bản giữa hai nền tảng thì chúng ta sẽ nhận được:lazy search for a text between two substrings then we will get:
re.search[r'pattern1[.*?]pattern2', s].group[1]
03 chuỗi riêng biệt như:
['Một số văn bản', 'văn bản nhiều hơn', 'sau đó nhiều văn bản hơn']