2010-09-17 18 views
11

Tôi có một chuỗi như thế nàychia với tràng duy nhất nhưng không phải ruột đôi sử dụng regex

"yJdz:jkj8h:jkhd::hjkjh" 

Tôi muốn chia nó sử dụng ruột như một tách, nhưng không phải là một dấu hai chấm đôi. kết quả mong muốn:

("yJdz", "jkj8h", "jkhd::hjkjh") 

Tôi đang cố gắng với:

re.split(":{1}", "yJdz:jkj8h:jkhd::hjkjh") 

nhưng tôi nhận được một kết quả sai.

Trong khi đó tôi thoát "::", với string.replace("::", "$$")

Trả lời

21

Bạn có thể chia tách trên (?<!:):(?!:). Điều này sử dụng hai negative lookarounds (một lookbehind và một lookahead) mà khẳng định rằng một trận đấu hợp lệ chỉ có một dấu hai chấm, không có dấu hai chấm trước hoặc sau dấu hai chấm.

Để giải thích các mô hình:

(?<!:) # assert that the previous character is not a colon 
:  # match a literal : character 
(?!:) # assert that the next character is not a colon 

Cả lookarounds là cần thiết, bởi vì nếu chỉ có các lookbehind, sau đó động cơ biểu thức chính quy sẽ phù hợp với ruột kết đầu tiên trong :: (vì nhân vật trước đó không phải là một dấu hai chấm), và nếu chỉ có dấu ấn, dấu hai chấm sẽ khớp nhau (vì ký tự tiếp theo không phải là dấu hai chấm).

11

Bạn có thể làm điều này với lookahead and lookbehind, nếu bạn muốn:

>>> s = "yJdz:jkj8h:jkhd::hjkjh" 
>>> l = re.split("(?<!:):(?!:)", s) 
>>> print l 
['yJdz', 'jkj8h', 'jkhd::hjkjh'] 

regex này chủ yếu nói "phù hợp với một : rằng không được theo sau bởi a : hoặc đi trước bởi một : "

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