2016-11-18 81 views
2

我需要轉換的用戶輸入中有字符串。這個用例很簡單:處理字符串中的轉義字符

  • 當字符串中有分號時,字符串被分成多行。
  • 當有連續兩個分號,他們正在轉化爲一個。

從理論上講,沒有什麼大問題。我使用Python,但我確信其他語言的其他人會發現這很容易使用正則表達式。

import re 

def get_lines(text): 
    """Return a list of lines (list of str).""" 
    command_stacking = ";" 
    delimiter = re.escape(command_stacking) 
    re_del = re.compile("(?<!{s}){s}(?!{s})".format(s=delimiter), re.UNICODE) 
    chunks = re_del.split(text) 

    # Clean the double delimiters 
    for i, chunk in enumerate(chunks): 
     chunks[i] = chunk.replace(2 * command_stacking, command_stacking) 

    return chunks 

,似乎工作:

>>> get_lines("first line;second line;third line with;;a semicolon") 
['first line', 'second line', 'third line with;a semicolon'] 
>>> 

但是,當有三個或四個分號,預期它不表現。

多重分號由正則表達式忽略(因爲他們應該),但由替換;;;,​​由;;取代,;;;;;;...等取代。如果2被1,3替換爲2,3替換爲3,這將是很好的...這是我可以向用戶解釋的東西。

什麼是做到這一點的最好的解決辦法?

感謝您的幫助,

回答

1

應用re.sub的REPL參數可以是一個函數。

>>> s = 'a;;b;;;c;;;;d' 
>>> pattern = ';{2,}' 
>>> def f(m): 
    return m.group(0)[1:] 

>>> re.sub(pattern, f, s) 
'a;b;;c;;;d' 
>>> 
1

取而代之的字符串replace方法使用re.sub()count=1

import re 
re.sub(';;', ';', 'foo;;;bar', count=1) 

https://docs.python.org/2/library/re.html#re.sub

+0

看起來像最好的解決方案,即使我不確定它是如何工作的。它似乎用一個,三個兩個,四個三個,五個四個等替換兩個分號。 –

+0

'count = 1'參數告訴它只替換一個雙分號的實例。 – Batman

0

您可以使用re.split用一下變通。

>>> re.split(r'(?<!;);(?!;)', string) 
['first line', 'second line', 'third line with;;a semicolon'] 

正則表達式

  • (?<!;)負的外觀後面。如果;檢查沒有被其他;
    • ;比賽之前提前;
  • (?!;)負的樣子。如果;檢查後面沒有另一個;

>>> [x.replace(';;', ';') for x in re.split(r'(?<!;);(?!;)', string)] 
['first line', 'second line', 'third line with;a semicolon']