tôi sẽ giải thích những gì xảy ra với mã của bạn:
import re
file = open('f1.txt')
fixed = open('fnew.txt','w')
text = file.read()
match = re.compile('<.*>')
for unwanted in text:
fixed_doc = match.sub(r' ',text)
fixed.write(fixed_doc)
Các hướng dẫn text = file.read()
tạo ra một đối tượng văn bản loại chuỗi tên text
.
Lưu ý rằng tôi sử dụng các ký tự in đậm văn bản để thể hiện OBJECT và text
để thể hiện tên == IDENTIFIER của đối tượng này.
Do hậu quả của hướng dẫn for unwanted in text:
, số nhận dạng unwanted
được gán liên tiếp cho từng ký tự được tham chiếu bởi đối tượng văn bản.
Bên cạnh đó, re.compile('<.*>')
tạo ra một đối tượng kiểu RegexObject (mà tôi personnaly gọi biên soạn) regex hoặc đơn giản là regex, <.*>
là chỉ mô hình regex).
Bạn chỉ định đối tượng regex đã biên dịch này cho số nhận dạng match
: đây là một phương pháp rất xấu, bởi vì match
đã là tên của một phương thức của các đối tượng regex nói chung và đối tượng bạn đã tạo cụ thể, sau đó bạn có thể viết match.match
lỗi.
match
cũng là tên của chức năng của mô-đun re.
Việc sử dụng tên này cho nhu cầu cụ thể của bạn là rất khó hiểu. Bạn phải tránh điều đó.
Có lỗi tương tự với việc sử dụng file
làm tên cho trình xử lý tệp của tệp f1. file
đã là một số nhận dạng được sử dụng trong ngôn ngữ, bạn phải tránh nó.
Vâng. Bây giờ trận đối tượng này xấu tên được định nghĩa, các hướng dẫn fixed_doc = match.sub(r' ',text)
thay thế tất cả các lần xuất hiện được tìm thấy bởi các regex trận đấu trong văn bản với sự thay thế r' '
.
Lưu ý rằng nó hoàn toàn không cần thiết để viết r' '
thay vì chỉ ' '
vì hoàn toàn không có gì trong ' '
cần phải được thoát. Đó là một mốt của một số người lo lắng để viết chuỗi thô mỗi khi họ phải viết một chuỗi trong một vấn đề regex.
Bởi vì mô hình của nó <.+>
trong đó chấm biểu tượng có nghĩa là "tham lam ăn mỗi nhân vật nằm giữa một <
và >
trừ khi đó là một ký tự xuống dòng", những lần xuất hiện đánh bắt trong đoạn văn bằng trận đấu là mỗi dòng cho đến khi cuối cùng là >
trong đó.
Vì tên unwanted
không xuất hiện trong hướng dẫn này, nó là cùng một thao tác được thực hiện cho từng ký tự của văn bản, cái này sau cái kia. Đó là để nói: không có gì thú vị.
Để phân tích việc thực hiện chương trình, bạn nên đặt một số hướng dẫn in trong mã của mình, cho phép để hiểu điều gì xảy ra.Ví dụ: nếu bạn thực hiện print repr(fixed_doc)
, bạn sẽ thấy bản in lặp lại của điều này: ' \n \n \n '
. Như tôi đã nói: không có gì thú vị cả.
Có thêm một mặc định trong mã của bạn: bạn mở tệp nhưng không đóng chúng. Nó là bắt buộc để đóng các tập tin, nếu không nó có thể xảy ra một số hiện tượng lạ, mà tôi personnally quan sát thấy trong một số mã của tôi trước khi tôi nhận ra nhu cầu này. Một số người giả vờ nó không phải là bắt buộc, nhưng nó sai.
Nhân tiện, cách tốt hơn để mở và đóng tệp là sử dụng câu lệnh with
. Nó làm tất cả công việc mà không cần phải lo lắng.
.
Vì vậy, bây giờ tôi có thể đề nghị bạn một mã cho vấn đề đầu tiên của bạn:
import re
def ripl(mat=None,li = []):
if mat==None:
li[:] = []
return
if mat.group(1):
li.append(mat.span(2))
return ''
elif mat.span() in li:
return ''
else:
return mat.group()
r = re.compile('</[^>]+>'
'|'
'<([^>]+)>(?=.*?(</\\1>))',
re.DOTALL)
text = '''<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>'''
print '1------------------------------------1'
print text
print '2------------------------------------2'
ripl()
print r.sub(ripl,text)
print '3------------------------------------3'
kết quả
1------------------------------------1
<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>
2------------------------------------2
George <wxc>Washington
Joe </zazaza>Taylor
3------------------------------------3
Nguyên tắc là như sau:
Khi regex phát hiện một thẻ,
- nếu đó là thẻ kết thúc, thẻ khớp với - nếu đó là thẻ bắt đầu, thẻ đó sẽ chỉ khớp nếu có thẻ kết thúc tương ứng ở đâu đó hơn nữa trong văn bản
Đối với mỗi trận đấu, phương pháp sub()
của regex r
gọi hàm ripl()
để thực hiện thay thế.
Nếu kết quả phù hợp với thẻ bắt đầu (cần phải tuân thủ một nơi nào đó trong văn bản bằng thẻ kết thúc tương ứng, bằng cách xây dựng regex), thì ripl()
trả về ''
.
Nếu kết hợp trùng với thẻ kết thúc, ripl()
chỉ trả lại ''
nếu thẻ kết thúc này trước đây trong văn bản được phát hiện là thẻ kết thúc tương ứng của thẻ bắt đầu trước đó. Điều này có thể thực hiện được bằng cách ghi lại trong danh sách li khoảng thời gian của mỗi thẻ kết thúc tương ứng mỗi khi thẻ bắt đầu được phát hiện và đối sánh.
Danh sách ghi li được định nghĩa là một đối số mặc định theo thứ tự mà nó luôn luôn cùng một danh sách được sử dụng tại mỗi cuộc gọi của hàm ripl()
(xin vui lòng, hãy tham khảo functionning của đối số mặc định để undertsand, bởi vì nó tinh tế).
Kết quả của định nghĩa li
là tham số nhận đối số mặc định, đối tượng danh sách li sẽ giữ lại tất cả các nhịp được ghi lại khi phân tích nhiều văn bản trong trường hợp một số văn bản sẽ được phân tích liên tiếp. Để tránh danh sách li để giữ lại các nhịp của các kết quả văn bản trong quá khứ, cần phải làm cho danh sách trống. Tôi đã viết hàm để tham số đầu tiên được xác định với đối số mặc định None
: cho phép gọi ripl()
mà không có đối số trước khi sử dụng bất kỳ tham số nào trong phương thức sub()
của regex.
Sau đó, người ta phải nghĩ đến việc viết ripl()
trước khi sử dụng.
.
Nếu bạn muốn loại bỏ các dòng mới của văn bản để có được kết quả chính xác mà bạn thấy trong câu hỏi của bạn, mã phải được sửa đổi để:
import re
def ripl(mat=None,li = []):
if mat==None:
li[:] = []
return
if mat.group(1):
return ''
elif mat.group(2):
li.append(mat.span(3))
return ''
elif mat.span() in li:
return ''
else:
return mat.group()
r = re.compile('(*\n *)'
'|'
'</[^>]+>'
'|'
'<([^>]+)>(?=.*?(</\\2>)) *',
re.DOTALL)
text = '''<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>'''
print '1------------------------------------1'
print text
print '2------------------------------------2'
ripl()
print r.sub(ripl,text)
print '3------------------------------------3'
kết quả
1------------------------------------1
<something @37>
<name>George <wxc>Washington</name>
<a23c>Joe </zazaza>Taylor</a23c>
</something @37>
2------------------------------------2
George <wxc>WashingtonJoe </zazaza>Taylor
3------------------------------------3
Xin chào. Trong vấn đề đầu tiên, ý định của bạn là xóa TẤT CẢ những gì trông giống như các thẻ, hoặc các thẻ thực sự xác định một phần tử của một ngôn ngữ đánh dấu? Tôi sử dụng từ 'nguyên tố' theo nghĩa chính xác và đúng của nó, có nghĩa là 'thẻ bắt đầu + nội dung phần tử + thẻ kết thúc'. - Ngoài ra, khi bạn tiếp xúc với nội dung của tập tin f, có những dòng trong đó, đó là để nói dòng mới trong đó. Những gì bạn cho thấy là kết quả mong muốn là một chuỗi trong đó không có thêm dòng mới. Nó thực sự là những gì bạn muốn hoặc bạn muốn giữ cấu trúc trong dòng? – eyquem
Bạn muốn nói gì với '' nếu value not in []) ''? Hiện nay nó không có ý nghĩa, vì luôn luôn không có gì trong một danh sách void. Bạn muốn làm gì khi so sánh các tệp? Nó không phải là rất rõ ràng – eyquem