Вопрос:
Почему следующее регулярное выражение возвращает пустые строки между ‘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 ” – конец строки (так же как .*$ соответствует пустой строке)