2017-02-01 10 views
1

Мы хотим группировать символы вместе между разрывами строк (\r\n, \n или \r), но игнорировать разрывы строк, которые встречаются внутри кавычек. Что-то вроде этого:отрицать соответствие шаблону регулярного выражения

test = 'hello \r\n you, hi, hola, "hei\nhei", hej\r\nhello, hi, hola, "hei\nhei", "hej\r\ngreat", you?' 

match -> hello 
match -> you, hi, hola, "hei\nhei", hej 
match -> hello, hi, hola, "hei\nhei", "hej\r\ngreat", you? 

Нам удалось получить что-то работу, которая соответствовала бы большинство наших потребностей, но она не игнорирует разрывы строк в кавычки:

In [342]: test = 'hello \r\n you, hi, hola, "hei\nhei", hej\r\nhello, hi, hola, "hei\nhei", "hej\r\ngreat", you?' 

In [343]: [r for r in re.finditer(r'([^(\r\n)])+', test)] 
Out[343]: 
[<_sre.SRE_Match object; span=(0, 6), match='hello '>, 
<_sre.SRE_Match object; span=(8, 28), match=' you, hi, hola, "hei'>, 
<_sre.SRE_Match object; span=(29, 38), match='hei", hej'>, 
<_sre.SRE_Match object; span=(40, 61), match='hello, hi, hola, "hei'>, 
<_sre.SRE_Match object; span=(62, 72), match='hei", "hej'>, 
<_sre.SRE_Match object; span=(74, 86), match='great", you?'>] 

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

In [344]: [r for r in re.finditer(r'(\r\n|\n)(?=(?:[^"]*"[^"]*")*[^"]*\Z)', test)] 
Out[344]: 
[<_sre.SRE_Match object; span=(6, 8), match='\r\n'>, 
<_sre.SRE_Match object; span=(38, 40), match='\r\n'>] 

Но мы не можем понять, как правильно его отрицания. Мы используем re.finditer(), а не re.split(), потому что хотим вернуть генератор.

+2

Это звучит как своего рода задачи, которые регулярное выражение не особенно хорошо подходит для анализа. Не могли бы вы вместо этого использовать что-то вроде 'pyparsing'? – mgilson

+1

Попробуйте 're.findall (r '(?:" [^ "] *" |.) +', Test) '. –

+0

Регулярные выражения плохо подходят для логики вложенности. – khelwood

ответ

3

Вы можете пойти с ([^"\r\n]*(?:"[^"]+"[^"\r\n]*)*).

Таким образом, вы найдете строку, не имеющую перевода строки или цитату, за которой может следовать любое количество строк в кавычках.

Demo.

import re,pprint 
test = 'hello \r\n you, hi, hola, "hei\nhei", hej\r\nhello, hi, hola, "hei\nhei", "hej\r\ngreat", you?' 
pprint.pprint(re.findall(r'([^\"\r\n]*(?:\"[^\"]+\"[^\"\r\n]*)*)', test)) 

выведет:

['hello ', 
' you, hi, hola, "hei\nhei", hej', 
'hello, hi, hola, "hei\nhei", "hej\r\ngreat", you?'] 
+0

это здорово, @Faibbus !!! Довольно многое, что нам нужно! Мы только что узнали, что для этого варианта использования он разделил бы новую строку: '' "\ r \ n" Привет, как вы \ r \ n \ r Я в порядке \ r \ n и вы? \ n alone in the dark \ n \ r \ n clean me \ n \ r kill me'' '[<_sre.SRE_Match object; span = (4, 21), match = 'Hello how are you'>, ... ' вместо: ' <_sre.SRE_Match объект; span = (4, 21), match = '"\ r \ n" Привет, как вы ">,' '...' – eberbis

+0

Хорошо, я не обрабатывал случаи, когда ваша строка начинается с '' '. – Faibbus

+0

Спасибо @Faibbus, мы будем использовать ваше решение! – eberbis