2011-08-19 31 views
5

Tôi có văn bản sau đây:Lấy văn bản bên trong # {}

#{king} for a ##{day}, ##{fool} for a #{lifetime} 

Và sau (bị hỏng) regex:

[^#]#{[a-z]+} 

Tôi muốn để phù hợp với tất cả # {lời} nhưng không phải là # # {words} (Nhân đôi '#' hoạt động như thoát).

Hôm nay tôi nhận thấy rằng regex tôi đã bỏ qua từ đầu tiên (từ chối khớp # {king}, nhưng bỏ qua chính xáC## {day} và ## {fool}).

>>> regex = re.compile("[^#]#{[a-z]+}") 
>>> regex.findall(string) 
[u' #{lifetime}'] 

Bất kỳ đề xuất nào về cách cải thiện regex hiện tại để phù hợp với nhu cầu của tôi? Tôi đoán vấn đề là với [^#] ...

Trả lời

6

Bạn phải sử dụng một "sự khẳng định lookbehind tiêu cực", regex chính xác sẽ trông giống như sau:

import re 
t = "#{king} for a ##{day}, ##{fool} for a #{lifetime}" 
re.findall(r'(?<!#)#{([a-z]+)}', t) 

trả về

['king', 'lifetime'] 

Giải thích:

Khái niệm (?<!prefix)pattern phù hợp pattern chỉ khi nó không preceeded bởi prefix.

+0

Giải pháp của bạn là tốt hơn, tôi quên mất tiêu cực nhìn phía sau. – grep

+0

Tính năng thú vị? Đây có phải là python pyex cụ thể không? –

+0

@Andrei, không có vẻ như nó không phải là python cụ thể (theo [trang web này] (http://www.regular-expressions.info/lookaround.html)), nhưng họ nói: "các hương vị như JavaScript, Ruby và Tcl làm không hỗ trợ ngoại hình, mặc dù họ hỗ trợ lookahead. " – MatToufoutu

0

thử điều này:

re.compile('^#\{[\w]+\}') 
+1

Bạn đã thử chưa? Nó chỉ khớp với '# {king}' nhưng cũng không phải '# {lifetime}'. – hughdbrown

+0

Tôi đã sửa chữa nó, nó sẽ hoạt động ngay bây giờ – prince

2

Sử dụng một cấu trúc lookbehind:

>>> s='#{king} for a ##{day}, ##{fool} for a #{lifetime}' 
>>> r=re.compile(r'(?:^|(?<=[^#]))#{\w+}') 
>>> r.findall(s) 
['#{king}', '#{lifetime}'] 
>>> 
2
>>> regex = re.compile("(?:^|[^#])#{[a-z]+}") 
>>> regex.findall(string) 
['#{king}', ' #{lifetime}'] 
>>> 
+1

Cần lưu ý rằng vấn đề với giải pháp này (không sử dụng xác nhận lookbehind tiêu cực) là nó sẽ không hoạt động với ''# {king} # {blah}'' - 'findall' trả về các kết quả trùng lặp không chồng chéo. –

1

Thay thế bằng (?:^|[^#]). Giống như bạn phỏng đoán, chỉ [^#] có nghĩa là một ký tự không phải là #, mà rõ ràng là không có ở đầu dòng.

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