python re, извлекать значения между запятыми

Вопрос: Почему следующее регулярное выражение возвращает пустые строки между 'a' и 'b'? In [48]: pat = re.compile(".*?(?=,|$)") In [49]: it = pat.findall('a,b') In [50]: it Out[50]: ['a', '', 'b', ''] Как получить подстроки между запятыми? EDIT: Мне любопытно, как это сделать, используя регулярные выражения. EDIT: Регулярное выражение должно успешно извлекать пустую строку дерева на этом

Вопрос:

Почему следующее регулярное выражение возвращает пустые строки между ‘a’ и ‘b’?

In [48]: pat = re.compile(«.*?(?=,|$)») In [49]: it = pat.findall(‘a,b’) In [50]: it Out[50]: [‘a’, », ‘b’, »]

Как получить подстроки между запятыми?

EDIT: Мне любопытно, как это сделать, используя регулярные выражения.

EDIT: Регулярное выражение должно успешно извлекать пустую строку дерева на этом входе “,”.

Лучший ответ:

  • .*? первые матчи потому, что следующий символ является a ,.
  • Движок регулярных выражений теперь на позиции до ,.
  • Теперь,. .*? соответствует пустой строке перед символом , (поскольку совпадение нулевой длины разрешено звездочкой).
  • Механизм регулярных выражений продвигает один символ после совпадения нулевой длины (он должен или он застрял здесь навсегда).
  • .*? теперь соответствует b потому что мы находимся в конце строки.
  • Механизм регулярных выражений теперь находится в конце строки.
  • .*? соответствует пустой строке до конца строки.
  • Строка исчерпана. Двигатель regex заканчивается.

Лучшим решением было бы просто разделить запятые.

Если вы настаиваете на использовании регулярного выражения, это немного сложнее, поскольку (согласно документам) re.findall() включает в себя пустые совпадения, если они не касаются начала другого совпадения. Это означает, что мы должны использовать положительное утверждение lookbehind вместо используемого вами взгляда.

Это, в свою очередь, означает, что мы не можем проверить разделитель и якорь начала строки в том же самом утверждении, поскольку Python не разрешает регулярные выражения переменной ширины в lookbehinds (sigh). Но это возможно так:

>>> re.findall(«(?:^|(?<=,))[^,]*», «a,b,,c») [‘a’, ‘b’, », ‘c’] Ответ №1

Вы можете сделать это:

st=’a,b, c , d, eeeee’ data=[e.strip() for e in st.split(‘,’)] print data # [‘a’, ‘b’, ‘c’, ‘d’, ‘eeeee’]

Или используйте csv:

for line in csv.reader(st.splitlines()): print line # [‘a’, ‘b’, ‘ c ‘, ‘ d’, ‘ eeeee’] # strip as you please

Или регулярное выражение:

print re.findall(r'([^,]+)(?:,|$)’, st) # [‘a’, ‘b’, ‘ c ‘, ‘ d’, ‘ eeeee’]

редактировать

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

>>> re.findall(r'[^,]+|,s*,’, ‘a,b, c ,, d, eeeee’) [‘a’, ‘b’, ‘ c ‘, ‘,,’, ‘ d’, ‘ eeeee’] Ответ №2

Я думаю, проблема заключается в том, что все ваше регулярное выражение состоит из “необязательного” символьного потребления до утверждения взгляда.

По мере продвижения позиции матча он может либо соответствовать чему-то, либо ничто.
Когда он ничего не соответствует, массив заполняется символом ».

Таким образом, a,b соответствует ‘a’, ”, ‘b’, ”
где final ” – конец строки (так же как .*$ соответствует пустой строке)

Оцените статью
Добавить комментарий