2013-03-22 92 views
4

我是新来的正则表达式,并与re.split功能有问题。re.split()特殊情况

在我的情况下,拆分必须关心“特殊逃脱”。

文本应该分开在;,除了有一个领先的?

编辑:在这种情况下,两个部分不应该拆分,?必须删除。

下面的例子,结果我想:

import re 
txt = 'abc;vwx?;yz;123' 
re.split(r'magical pattern', txt) 
['abc', 'vwx;yz', '123'] 

我试过到目前为止这些尝试:

re.split(r'(?<!\?);', txt) 

,并得到:

['abc', 'vwx?;yz', '123'] 

可悲的是导致不消耗?麻烦和以下列表理解是对性能至关重要:

[part.replace('?;', ';') for part in re.split(r'(?<!\?);', txt)] 
['abc', 'vwx;yz', '123'] 

有没有一种“快速”的方式来重现这种行为?

re.findall函数可以作为解决方案吗?

例如一个扩展版本的代码:

re.findall(r'[^;]+', txt) 

我使用Python 2.7.3。

感谢您的期待!

+0

所以你想要的是* two * things:要分割';',并* remove *'''escape c来自'?;'的字符分裂后正确? – 2013-03-22 16:40:36

+0

是的,没错。 – MaM 2013-03-22 16:42:28

+2

因为这是两个不同的任务,所以你的方法已经是正确的了。 – 2013-03-22 16:44:43

回答

0

你不能用一个正则表达式做你想做的事。拆分之后的拆分?;完全是一项单独的任务,而不是您可以在同时拆分时获得re模块为您执行的任务。

只是保持任务分开;你可以使用一个发电机来为你做转换:

def unescape(iterable): 
    for item in iterable: 
     yield item.replace('?;', ';') 

for elem in unescape(re.split(r'(?<!\?);', txt)): 
    print elem 

但这不会比你的列表理解更快。

+0

谢谢大家的快速解答和解决方法的想法。我会接受这个答案,因为看起来没有办法只用一个正则表达式来实现这个任务。 – MaM 2013-03-28 08:03:26

5

正则表达式不是工作的工具。使用csv模块来代替:

>>> txt = 'abc;vwx?;yz;123' 
>>> r = csv.reader([txt], delimiter=';', escapechar='?') 
>>> next(r) 
['abc', 'vwx;yz', '123'] 
0

我会做这样的:

re.sub('(?<!\?);',r'|', txt).replace('?;',';').split('|') 
0

试试这个:-)

def split(txt, sep, esc, escape_chars): 
    ''' Split a string 
     txt - string to split 
     sep - separator, one character 
     esc - escape character 
     escape_chars - List of characters allowed to be escaped 
    ''' 
    l = [] 
    tmp = [] 
    i = 0 
    while i < len(txt): 
     if len(txt) > i + 1 and txt[i] == esc and txt[i+1] in escape_chars: 
      i += 1 
      tmp.append(txt[i]) 
     elif txt[i] == sep: 
      l.append("".join(tmp)) 
      tmp = [] 
     elif txt[i] == esc: 
      print('Escape Error') 
     else: 
      tmp.append(txt[i]) 
     i += 1 
    l.append("".join(tmp)) 
    return l 

if __name__ == "__main__": 
    txt = 'abc;vwx?;yz;123' 
    print split(txt, ';', '?', [';','\\','?']) 

返回:

['abc', 'vwx;yz', '123']