使用re.split分割字符串

时间:2014-02-17 22:48:24

标签: python regex django string

我有以下形式的多个字符串(> 1000):

\r\nSenor Sisig\nThe Chairman\nCupkates\nLittle Green Cyclo\nSanguchon\nSeoul on Wheels\nKasa Indian\n\nGo Streatery\nWhip Out!\nLiba Falafel\nGrilled Cheese Bandits\r\n

字符串在'\ n'

之前可能有一个空格

如何拆分这些字符串(以有效的方式),以避免得到任何空的或重复的(空白案例)元素?

我正在使用:

re.split(r'\r|\n', str)

编辑: 更多例子:

\r\nThe Creme Brulee Cart \r\nCurry Up Now\r\nKoJa Kitchen\r\nAn the Go\r\nPacific Puffs\r\nEbbett's Good to Go\r\nFiveten Burger\r\nGo Streatery\r\nHiyaaa\r\nSAJJ\r\nKinder's Truck\r\nBlue Saigon\r
\r\nThe Chairman\r\nSanguchon\r\nSeoul on Wheels\r\nGo Streatery\r\nStreet Dog Truck\r\nKinder's Truck\r\nYummi BBQ\r\nLexie's Frozen Custard\r\nDrewski's Hot Rod Kitchen\r
\n An the Go \n Cheese Gone Wild \n Cupkates \n Curry Up Now \n Fins on the Hoof\n KoJa Kitchen\n Lobsta Truck \n Oui Chef \n Sanguchon\n Senor Sisig \n The Chairman \n The Rib Whip 

谢谢!

4 个答案:

答案 0 :(得分:2)

除了单个可选\n之外,您的示例不会在\r之前显示任何“空白”。

如果这是您要处理的全部内容,而不是分为\r\n,请分开可能的\r和明确的\n

re.split(r"\r?\n", s)

当然,假设你没有\r没有\n来处理。如果您需要同等处理\r\r\n\n(类似于Python的通用换行支持...):

re.split(r"\r|\n|(\r\n)", s)

或者更简单:

re.split(r"(\r|\n)+", s)

如果要删除前导空格,制表符,多个\r等,可以在正则表达式中执行此操作,或者只在每个结果上调用lstrip

map(str.lstrip, re.split(r"\r|\n", s))

...但是这可能会让你失去空元素。你可以过滤掉那些,但最好只拆分任何以\n结尾的空格:

re.split(r"\s*\n", s)

那仍然会在开头和结尾留下空元素,因为你的字符串以换行符开头和结尾,这就是re.split应该做的事情。如果你想消除它们,你可以在解析之前strip字符串,或者在解析之后抛出结束值:

re.split(r"\s*\n", s.strip())
re.split(r"\s*\n", s)[1:-1]

我认为最后两个中的一个正是你想要的......但这只是基于你给出的有限信息的猜测。如果没有,那么其他一个(连同它的解释)应该足以让你写出你真正想要的东西。


从您的新示例中,您真正想要拆分的是任何包含至少一个\n的空白行。你的输入可能有也可能没有开头和结尾的换行符(你的第一个例子有两个,你的第二个开头有\r\n但最后没有...),如果有的话你想忽略它们。所以:

re.split(r"\s*\n\s*", s.strip())

然而,在这一点上,可能值得问为什么你试图将其解析为字符串而不是文本文件。假设您从某个文件或类似文件的对象中获取了这些内容,而不是:

with open(path, 'r') as f:
    s = f.read()
    results = re.split(regexpr, s.strip())

...像这样的东西可能更具可读性,而且速度足够快(可能没有最佳正则表达式快,但仍然如此之快,以至于任何浪费的字符串处理时间都被实际的文件读取时间所淹没) :

with open(path, 'r') as f:
    results = filter(None, map(str.strip, f))

特别是如果您只想迭代此列表一次,在这种情况下(假设是Python 3.x,或使用来自ifilter的{​​{1}}和imap,如果是2.x)此版本不必将整个文件读入内存并在开始实际工作之前对其进行处理。

答案 1 :(得分:1)

re.split(r'[\s\n\r]+', str.strip())

答案 2 :(得分:0)

只过滤掉空值

list(ifilter(None, re.split(r"\r|\n", your_string)))

Pythons正则表达式为您提供\s - 字符类,它匹配[ \t\n\r\f\v]中的任何空格(除非设置了UNICODE标志,否则它取决于正在使用的字符数据库)。

正如其他答案(@abarnert)中所提到的,你的正则表达式可能\s*\n,其中0或更多的空格以\n结尾。以下是一个例子。

In [1]: import re 

In [2]: from itertools import ifilter

In [3]: my_string = """\r\nSenor Sisig \nThe Chairman\nCupkates\nLittle Green Cyclo\nSanguchon\nSeoul on Wheels\nKasa Indian\n\nGo Streatery\nWhip Out!\nLiba Falafel\nGrilled Cheese Bandits\r\n"""

In [4]: list(ifilter(None, re.split(r"\s*\n", my_string)))
Out[4]: 
['Senor Sisig',
 'The Chairman',
 'Cupkates',
 'Little Green Cyclo',
 'Sanguchon',
 'Seoul on Wheels',
 'Kasa Indian',
 'Go Streatery',
 'Whip Out!',
 'Liba Falafel',
 'Grilled Cheese Bandits']

请注意,我正在使用itertools package中的ifilter。您可以使用filter或列表comp。

像这样:

[x for x in re.split("\s*\n", my_string) if x]

答案 3 :(得分:0)

>>> s = "\r\nSenor Sisig\nThe Chairman\nCupkates\nLittle Green Cyclo\nSanguchon\nSeoul on Wheels\nKasa Indian\n\nGo Streatery\nWhip Out!\nLiba Falafel\nGrilled Cheese Bandits\r\n"
>>> [x for x in s.strip("\r\n").split("\n") if x]
['Senor Sisig', 'The Chairman', 'Cupkates', 'Little Green Cyclo', 'Sanguchon', 'Seoul on Wheels', 'Kasa Indian', 'Go Streatery', 'Whip Out!', 'Liba Falafel', 'Grilled Cheese Bandits']

如果你坚持使用正则表达式

>>> import re
>>> re.split(r"[\r\n]+", s.strip("\r\n"))
['Senor Sisig', 'The Chairman', 'Cupkates', 'Little Green Cyclo', 'Sanguchon', 'Seoul on Wheels', 'Kasa Indian', 'Go Streatery', 'Whip Out!', 'Liba Falafel', 'Grilled Cheese Bandits']
相关问题