Сплит с одиночным двоеточием, но не двойной двоеточие с использованием регулярного выражения

У меня есть строка, подобная этой

"yJdz:jkj8h:jkhd::hjkjh"

Я хочу разбить его с помощью двоеточия в качестве разделителя, но не на двойной двоеточие. Желаемый результат:

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

Я пытаюсь:

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

но я получил неправильный результат.

В то же время я избегаю "::", string.replace("::", "$$")

Ответ 1

Вы можете разделить на (?<!:):(?!:). Это использует два негативные образы (lookbehind и lookahead), которые утверждают, что допустимое соответствие имеет только один двоеточие без двоеточия до или после него.

Чтобы объяснить шаблон:

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

Оба искажения необходимы, потому что если бы существовал только внешний вид, то механизм регулярного выражения соответствовал первому двоеточию в :: (потому что предыдущий символ не является двоеточием), и если бы был только просмотр, второй двоеточие будет соответствовать (потому что следующий символ не является двоеточием).

Ответ 2

Вы можете сделать это с помощью lookahead и lookbehind, если хотите:

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

Это регулярное выражение, по существу, говорит: "соответствовать a :, за которым не следует : или предшествует :"