2008-08-17 29 views
11

Tôi đang cố gắng triển khai chuỗi không thoát với Python regex và backreferences, và nó dường như không muốn hoạt động rất tốt. Tôi chắc chắn đó là điều tôi đang làm sai nhưng tôi không thể tìm ra những gì ...Biểu thức chính quy của Python để triển khai chuỗi không bị cắt nghĩa

>>> import re 
>>> mystring = r"This is \n a test \r" 
>>> p = re.compile("\\\\(\\S)") 
>>> p.sub("\\1", mystring) 
'This is n a test r' 
>>> p.sub("\\\\\\1", mystring) 
'This is \\n a test \\r' 
>>> p.sub("\\\\1", mystring) 
'This is \\1 a test \\1' 

Tôi muốn thay thế \\ [char] bằng \ [char] nhưng backreferences in Python dường như không tuân theo các quy tắc tương tự mà họ thực hiện trong mọi triển khai khác mà tôi từng sử dụng. Ai đó có thể làm sáng tỏ không?

Trả lời

8

Đó không phải là những gì Anders 'ví dụ thứ hai làm gì?

Trong 2.5 cũng có một string-escape mã hóa, bạn có thể áp dụng:

>>> mystring = r"This is \n a test \r" 
>>> mystring.decode('string-escape') 
'This is \n a test \r' 
>>> print mystring.decode('string-escape') 
This is 
a test 
>>> 
3

Vâng, tôi nghĩ bạn có thể đã bỏ lỡ r hoặc miscounted những dấu xồ nguợc ...

"\\n" == r"\n" 

>>> import re 
>>> mystring = r"This is \\n a test \\r" 
>>> p = re.compile(r"[\\][\\](.)") 
>>> print p.sub(r"\\\1", mystring) 
This is \n a test \r 
>>> 

nào, nếu tôi hiểu là những gì được yêu cầu.

tôi nghi ngờ yêu cầu phổ biến hơn là thế này:

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'} 
>>> p = re.compile(r"[\\]([nrfv])") 
>>> print p.sub(lambda mo: d[mo.group(1)], mystring) 
This is \ 
a test \ 
>>> 

Học sinh quan tâm cũng nên đọc Ken Thompson Reflections on Trusting Trust", trong đó anh hùng của chúng tôi sử dụng một ví dụ tương tự để giải thích sự nguy hiểm của các trình biên dịch tin tưởng bạn chưa bootstrapped từ mã máy của bạn.

0

Bạn đang bị lừa bởi trình bày của Python về chuỗi kết quả. Khái niệm Python:

'This is \\n a test \\r' 

đại diện cho chuỗi

This is \n a test \r 

đó là tôi nghĩ rằng những gì bạn muốn. Thử thêm 'print' vào trước mỗi p.sub() của bạn để in chuỗi thực sự được trả về thay vì biểu diễn Python của chuỗi.

>>> mystring = r"This is \n a test \r" 
>>> mystring 
'This is \\n a test \\r' 
>>> print mystring 
This is \n a test \r 
0

Ý tưởng là tôi sẽ đọc trong một chuỗi trốn thoát, và không dò nó (một tính năng đáng chú ý là thiếu từ Python, mà bạn không cần phải dùng đến biểu thức thông thường để ở nơi đầu tiên). Đáng tiếc là tôi không bị lừa bởi những dấu xồ nguợc ...

Một ví dụ minh họa:

>>> mystring = r"This is \n ridiculous" 
>>> print mystring 
This is \n ridiculous 
>>> p = re.compile(r"\\(\S)") 
>>> print p.sub('bloody', mystring) 
This is bloody ridiculous 
>>> print p.sub(r'\1', mystring) 
This is n ridiculous 
>>> print p.sub(r'\\1', mystring) 
This is \1 ridiculous 
>>> print p.sub(r'\\\1', mystring) 
This is \n ridiculous 

Những gì tôi muốn nó in là

This is 
ridiculous 
0

Đánh dấu; ví dụ thứ hai của ông yêu cầu mỗi ký tự thoát được ném vào một mảng ban đầu, tạo ra một KeyError nếu trình tự thoát không xảy ra trong mảng. Nó sẽ chết bất cứ thứ gì trừ ba ký tự được cung cấp (cho \ v một lần thử), và liệt kê mọi chuỗi thoát có thể xảy ra mỗi khi bạn muốn unescape một chuỗi (hoặc giữ một mảng toàn cầu) là một giải pháp thực sự tồi. Tương tự như PHP, sử dụng preg_replace_callback() với lambda thay vì preg_replace(), điều này hoàn toàn không cần thiết trong tình huống này.

Tôi xin lỗi nếu tôi sắp trở thành một kẻ lừa đảo, tôi hoàn toàn thất vọng với Python.Điều này được hỗ trợ bởi mọi công cụ biểu thức chính quy khác mà tôi từng sử dụng và tôi không thể hiểu tại sao điều này không hiệu quả.

Cảm ơn bạn đã trả lời; chức năng string.decode('string-escape') là chính xác những gì tôi đang tìm kiếm ban đầu. Nếu ai đó có một giải pháp chung cho vấn đề backreference regex, cảm thấy tự do để đăng nó và tôi sẽ chấp nhận rằng như là một câu trả lời là tốt.

Các vấn đề liên quan