2014-04-12 4 views
0

Я пытаюсь разобрать следующую строкуКак разбирать строку с помощью регулярного выражения?

s1 = """ "foo","bar", "foo,bar" """ 

И вне положенный этого разборе я надеюсь, это ...

List ["foo","bar","foo,bar"] length 3 

Я могу разобрать следующие

s2 = """ "foo","bar", 'foo,bar' """ 

По следующей схеме

pattern = "(('[^']*')|([^,]+))" 
re.findall(pattern,s2) 
gives [('foo', '', 'foo'), ('bar', '', 'bar'), ("'foo,bar'", "'foo,bar'", '')] 

Но я не могу понять, шаблон для s2 .. Обратите внимание, что мне нужно разобрать и s1 и s2 успешно

Edit 
    The current pattern support strings like 
    "foo,bar,foo bar" => [foo,bar,foo bar] 
    "foo,bar,'foo bar'" => ["foo","bar",'foo bar'] 
    "foo,bar,'foo, bar'" => [foo,bar, 'foo, bar'] #length 3 
+0

Что такое '«»" ' – aliteralmind

+0

@aliteralmind Начало и конец строки буквальным – TerryA

+0

Я использую это: http://regex101.com/#python – Roberto

ответ

1

Это работает:

(?:"([^"]+)"|'([^']+)') 

Regular expression visualization

Debuggex Demo

Захват группы 1 или два содержат желаемый результат. Таким образом, каждый элемент может быть $1$2, потому что точно один всегда будет пустым.


Обновлено к новым требованиям, как в комментариях к ответу Haidro в:

(?:("[^"]+")|('[^']+')|(\w+)) 

Regular expression visualization

Debuggex Demo

Каждый элемент теперь $1$2$3.

+0

@ Хайдо: Обновлено. – aliteralmind

2

Может быть, вы могли бы использовать что-то вроде этого:

>>> re.findall(r'["|\'](.*?)["|\']', s1) 
['foo', 'bar', 'foo,bar'] 
>>> re.findall(r'["|\'](.*?)["|\']', s2) 
['foo', 'bar', 'foo,bar'] 

Это находит все слова внутри "..." или '...' и группирует их.

+0

@Hairdo Спасибо за образец. он работает .. но он терпит неудачу в «foo, bar, foobar». Возможно ли это поддержать? – Fraz

+0

Итак, некоторые строки * не * цитируются? Было бы совершенно иначе, чтобы захватить неучтенные строки. – aliteralmind

+0

@ Хайдо: Я немного обновил прецедент ... можем ли мы поддержать эти случаи? – Fraz

4

Я думаю, что shlex (simple lexical analysis) здесь намного проще (когда regex слишком сложно). В частности, я хотел бы использовать:

>>> import shlex 
>>> lex = shlex.shlex(""" "foo","bar", 'foo,bar' """, posix=True) 
>>> lex.whitespace = ','  # Only comma will be a splitter 
>>> lex.whitespace_split=True # Split by any delimiter defined in whitespace 
>>> list(lex)     # It is actually an generator 
['foo', 'bar', 'foo,bar'] 

Edit:

У меня есть ощущение, что вы пытаетесь прочитать файл CSV. Вы пробовали import csv?

+0

Довольно крутое решение. Я думаю, вы имеете в виду, что 'lex' является генератором, и поэтому нам нужно вызвать' list() '. Список - это итератор. – TerryA

+0

@Haidro - Я всегда думал, что итератор - это объект, который позволяет вам выполнять итерацию, а генератор - это функция, которая позволяет вам выполнять итерацию (используя выход). Я все равно изменил его. – tmrlvi

Смежные вопросы