2011-12-12 10 views
6

Próbuję utworzyć wyrażenie regularne pasujące do wyrażeń regularnych między dwoma ukośnikami. Moim głównym problemem jest to, że same wyrażenia regularne mogą zawierać ukośniki w przód, zbiegające przez ukośnik odwrotny. Próbuję odfiltrować je za pomocą ujemnego asercji lookbehind (pasuje tylko do slotu zamykającego, jeśli nie ma luzu w bieżącej pozycji), jednak mam teraz problem, że nie dostaję dopasowania, jeśli samo wyrażenie regularne w rzeczywistości kończy się uciekającym ukośnikiem odwrotnym.Wyrażenie regularne: dopasuj ciąg pomiędzy dwoma ukośnikami, jeśli ciąg zawiera ukośne ukośniki

program testowy:

#!/usr/bin/python 
import re 
teststrings=[ 
    """/hello world/""", 
    """/string with foreslash here \/ and here\//""", 
    """/this one ends with backlash\\\\/"""] 

patt="""^\/(?P<pattern>.*)(?<!\\\\)\/$""" 

for t in teststrings: 
    m=re.match(patt,t) 
    if m!=None: 
     print t,' => MATCH' 
    else: 
     print t," => NO MATCH" 

wyjściowa:

/hello world/ => MATCH 
/string with foreslash here \/ and here\// => MATCH 
/this one ends with backlash\\/ => NO MATCH 

Jak zmodyfikować twierdzenie tylko hit czy istnieje pojedynczy luz w bieżącym położeniu, ale nie dwa?

Czy istnieje lepszy sposób wyodrębnienia wyrażenia regularnego? (Uwaga, w rzeczywistym pliku próbuję analizować wiersze zawierają więcej niż tylko regex I nie można po prostu sprawdzić w pierwszym i ostatnim ukośniku na linię i dostać wszystko pomiędzy nimi.).

+0

W przykładzie świecie rzeczywistym, mogłeś uciekły ukośniki przed/po raz pierwszy/ostatni „prawdziwy” ciąć? –

+0

Tak, ciąg po wyrażeniu regularnym może mieć dowolne znaki, w tym ukośniki. – Gryphius

Odpowiedz

16

Spróbuj:

pattern = re.compile(r"^/(?:\\.|[^/\\])*/") 

Objaśnienie:

^  # Start of string 
/  # Match/
(?:  # Match either... 
\\. # an escaped character 
|  # or 
[^/\\] # any character except slash/backslash 
)*  # any number of times. 
/  # Match/

na swoim "świecie rzeczywistym" aplikacji (znalezieniu pierwszego "ciąg rozdzielany slash", nie zważając uciekły ukośniki), użyję

pattern = re.compile(r"^(?:\\.|[^/\\])*/((?:\\.|[^/\\])*)/") 

ten dostaje co następuje:

>>> pattern.match("foo /bar/ baz").group(1) 
'bar' 
>>> pattern.match("foo /bar\/bam/ baz").group(1) 
'bar\\/bam' 
>>> pattern.match("foo /bar/bam/ baz").group(1) 
'bar' 
>>> pattern.match("foo\/oof /bar\/bam/ baz").group(1) 
'bar\\/bam' 
+2

Myślę, że potrzebujesz '\\.', Aby dopasować znak z Escaped. – interjay

+0

Ups. Tak, dziękuję. Zmodyfikuję ... –

+0

idealne! wielkie dzięki! – Gryphius

Powiązane problemy