2010-01-26 8 views
7

Piszę parser za pomocą ply, który musi zidentyfikować literały ciągów FORTRAN. Są one cytowane za pomocą pojedynczych cudzysłowów, a znak ucieczki to podwójny pojedynczy cudzysłów. tjJak napisać wyrażenie regularne, aby dopasować literał ciągu znaków, gdzie escape jest podwojeniem znaku cudzysłowu?

'I don''t understand what you mean'

jest prawidłowy ciąg FORTRAN uciekł.

Ply pobiera dane wejściowe w wyrażeniu regularnym. Moja dotychczasowa próba nie działa i nie rozumiem dlaczego.

t_STRING_LITERAL = r"'[^('')]*'"

Jakieś pomysły?

Odpowiedz

20

Łańcuch znaków jest:

  1. Otwarta apostrofu, a następnie:
  2. dowolna liczba podwoiła-single-cytaty i non-single-cytaty, a następnie
  3. Bliskie pojedynczy cytatem .

Zatem nasza regex jest:

r"'(''|[^'])*'" 
+1

Ah Zen wyrażeń regularnych, dzięki! – Brendan

+1

Wydaje się, że nie radzi sobie z sekwencjami ucieczkowymi. – Cyoce

4

Chcesz coś takiego:

r"'([^']|'')*'" 

Ten mówi, że wewnątrz pojedynczych cudzysłowów można mieć albo cudzysłów albo ich nie- cytuj charakter.

Nawiasy definiują klasę znaków, w której wymienione są znaki, które mogą lub nie. Nie zezwala na nic bardziej skomplikowanego, więc próba użycia nawiasów i dopasowanie wielokrotnej sekwencji znaków nie działa. Zamiast tego twoja klasa znaków [^('')] jest odpowiednikiem [^'()], tj. Dopasowuje wszystko, co nie jest pojedynczym cudzysłowem lub lewym lub prawym nawiasem.

0

Zazwyczaj łatwo dostać coś szybkie i brzydka do analizowania konkretnych literały ciągów znaków, które dają Ci problemy, ale dla ogólnego rozwiązania można uzyskać bardzo mocny i kompletny regex napisowych z pyparsing module:

>>> import pyparsing 
>>> pyparsing.quotedString.reString 
'(?:"(?:[^"\\n\\r\\\\]|(?:"")|(?:\\\\x[0-9a-fA-F]+)|(?:\\\\.))*")|(?:\'(?:[^\'\\n\\r\\\\]|(?:\'\')|(?:\\\\x[0-9a-fA-F]+)|(?:\\\\.))*\')' 

Nie mam pewności co do istotnych różnic między literałami ciągów FORTRANA a literami Pythona, ale jest to przydatne odniesienie, jeśli nic więcej.

0
import re 

ch ="'I don''t understand what you mean' and you' ?" 

print re.search("'.*?'",ch).group() 
print re.search("'.*?(?<!')'(?!')",ch).group() 

wynik

'I don' 
'I don''t understand what you mean' 
Powiązane problemy