2013-02-04 12 views
18

Trochę zagubiłem się o surowy ciąg znaków Python. Wiem, że jeśli użyjemy nieprzetworzonego łańcucha, to będzie traktować "\" jako normalny ukośnik odwrotny (np. R \ n "będzie" \ "i" n "). Zastanawiałem się jednak, co zrobić, jeśli chcę dopasować nowy ciąg znaków do surowego ciągu znaków. Próbowałem r \ n ", ale to nie zadziałało. Ktoś ma jakieś dobre pojęcie na ten temat?Jak dopasować znak nowego wiersza w nieprzetworzonym łańcuchu Python

+0

Jakie meczu mówimy tutaj? Czy mówisz o dopasowaniu do wyrażenia regularnego lub po prostu 'if ... in my_raw_string'? – mgilson

+0

Przepraszam, że wprowadzam Cię w błąd. Mówię o regularnym wyrażeniu. – wei

Odpowiedz

17

w wyrażeniu regularnym, trzeba określić, że jesteś w trybie wielowierszowego:

>>> import re 
>>> s = """cat 
... dog""" 
>>> 
>>> re.match(r'cat\ndog',s,re.M) 
<_sre.SRE_Match object at 0xcb7c8> 

Uwaga, re tłumaczy \n (surowy ciąg) do nowej linii. Jak wskazano w komentarzach, nie faktycznie potrzebare.M na to, aby dopasować, ale to nie pomaga z pasującymi $ i ^ bardziej intuicyjnie:

>> re.match(r'^cat\ndog',s).group(0) 
'cat\ndog' 
>>> re.match(r'^cat$\ndog',s).group(0) #doesn't match 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'NoneType' object has no attribute 'group' 
>>> re.match(r'^cat$\ndog',s,re.M).group(0) #matches. 
'cat\ndog' 
+0

Dzięki za odpowiedź @mgilson! Chciałbym również wiedzieć, dlaczego musimy określić tryb multilinii. Próbowałem dopasowywania bez niego, jak ten "re.match (r'cat \ ndog", s) "i nadal działa. – wei

+0

@ user1783403 - Masz rację. Więcej powinienem przeczytać w dokumentacji. określenie 're.M' pobiera'^'i' $ ', aby dopasować bardziej intuicyjnie. – mgilson

+0

Jakikolwiek sposób, aby '$' dopasować "mniej intuicyjnie" - tj. Aby dopasować * tylko * na końcu łańcucha? Nie chcę, żeby to się zgadzało przed '\ n' –

4

Najprostsza odpowiedź to po prostu nie używać nieprzetworzonego łańcucha. Możesz uciec przed ukośnikami, używając \\.

Jeśli masz ogromną liczbę ukośniki w niektórych segmentach, a następnie można łączyć surowe ciągi i normalne ciągi jako potrzebne:

r"some string \ with \ backslashes" "\n" 

(Python automatycznie skleja literały ciągów tylko z odstępami między nimi.)

Pamiętaj, że jeśli pracujesz z ścieżkami w systemie Windows, najprościej jest po prostu użyć ukośników - nadal będzie działać poprawnie.

+0

@mgilson Właśnie sprawdzałem, czy działa z nieprzetworzonymi łańcuchami i normalnymi ciągami, ponieważ to nie jest coś, co zrobiłem. Edytowane tak jak to. Jest to trochę lepsze, ponieważ uważam, że konkatenacja odbywa się w czasie parsowania, a nie wtedy, gdy jest wykonywana. –

+0

Tak, nigdy wcześniej nie sprawdzałem :) – mgilson

+0

Dlaczego -1 na tym? –

0
def clean_with_puncutation(text):  
    from string import punctuation 
    import re 
    punctuation_token={p:'<PUNC_'+p+'>' for p in punctuation} 
    punctuation_token['<br/>']="<TOKEN_BL>" 
    punctuation_token['\n']="<TOKEN_NL>" 
    punctuation_token['<EOF>']='<TOKEN_EOF>' 
    punctuation_token['<SOF>']='<TOKEN_SOF>' 
    #punctuation_token 



    regex = r"(<br/>)|(<EOF>)|(<SOF>)|[\n\!\@\#\$\%\^\&\*\(\)\[\]\ 
      {\}\;\:\,\.\/\?\|\`\_\\+\\\=\~\-\<\>]" 

###Always put new sequence token at front to avoid overlapping results 
#text = '<EOF>[email protected]#$%^&*()[]{};:,./<>?\|`~-= _+\<br/>\n <SOF>\ ' 
    text_="" 

    matches = re.finditer(regex, text) 

    index=0 

    for match in matches: 
    #print(match.group()) 
    #print(punctuation_token[match.group()]) 
    #print ("Match at index: %s, %s" % (match.start(), match.end())) 
     text_=text_+ text[index:match.start()] +" " 
       +punctuation_token[match.group()]+ " " 
     index=match.end() 
    return text_ 
Powiązane problemy