python 拆分字符串反斜杠_python编程技巧2_1拆分多种分隔符的字符串

本文介绍了如何在Python中拆分包含多种分隔符(如';', '|', ' ')的字符串。提出了两种解决方案:一是连续使用`str.split()`方法,二是利用正则表达式的`re.split()`方法。文章详细解析了这两种方法的实现过程,并提供了封装接口的示例。" 8956910,301770,GML在地理空间数据可视化中的应用,"['地理空间数据', '数据可视化', 'GIS', 'XML应用', 'Web服务']
摘要由CSDN通过智能技术生成

心存善意,定能途遇天使。

有这样一字符串,'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz',如何根据分隔符 ; , | \t 进行拆分?

解决方案:

方案一:连续使用str.split()方法,每次只能处理一种分隔号

        ■ map()+str.split()

        ■ sum()+str.split()

        ■ reduce()+map()+sum()+str.split()

方案二:使用正则表达式的re.split()方法。(推荐!!!)

PS: 处理一个分隔符的时候使用方法一(一个的时候,方法二会比一慢);多个分隔符的时候使用方法二


连续使用str.split()

aa98f642-bb37-eb11-8da9-e4434bdf6706.svg

我们先来小试牛刀。

In [1]: s = 'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz'# 注意: str.split('|,;') 这样写的话 会将 |,; 整体当作成1个分隔符In [2]: s.split('|')Out[2]: ['ab;cd', 'efg', 'hi,jkl', 'mn\topq;rst,uvw\txyz']In [3]: [ss.split(';') for ss in s.split('|')]Out[3]: [['ab', 'cd'], ['efg'], ['hi,jkl'], ['mn\topq', 'rst,uvw\txyz']]
不难看出,当第二次分割的时候,分割结果就变成了二维了。我们需要使用str.split()继续分割,就必须进行降维处理,将二维变成一维。降维处理,可以使用前面学到的 map()函数 ,还可以使用sum()函数。 先注意一个列表添加的小细节,append()跟extend()有着很大的不同。
In [13]: t1 = []In [14]: t1.append(['ab', 'cd'])# 添加的是列表In [15]: t1Out[15]: [['ab', 'cd']]In [16]: t2 = []In [17]: t2.extend(['ab', 'cd'])# 添加的是列表里的元素In [18]: t2Out[18]: ['ab', 'cd']
map()函数依次作用于序列的每一个元素,并返回一个生成器,这时候,我们就应该想到使用map()操作二维里面的每一个元素,如何个操作法呢?因为二维里的这些个元素是列表,所以使用extend()添加进新的列表里,就实现了降维。
In [1]: s = 'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz'In [3]: [ss.split(';') for ss in s.split('|')]Out[3]: [['ab', 'cd'], ['efg'], ['hi,jkl'], ['mn\topq', 'rst,uvw\txyz']]In [19]: t = []# 注意 这里map返回的结果是[None,None,None,None] 因为东西都到t列表里去啦.# 还要注意一点 map()映射函数 最终结果是生成器!!!!!!!# 不使用list()、tuple()将其序列化的话 里面是不会依次next()运行的 在这里就意味着t依旧是空列表In [20]: list(map(lambda x: t.extend(x), [ss.split(';') for ss in s.split('|')]))Out[20]: [None, None, None, None]In [21]: tOut[21]: ['ab', 'cd', 'efg', 'hi,jkl', 'mn\topq', 'rst,uvw\txyz']

再来琢磨琢磨sum()函数,使用sum()函数将二维转变为一维 "这种方式会有些浪费"。sum(iterable,start=0,/) 设置初始值为空列表。

其执行过程就是空列表与可迭代序列里的每一个元素相加,而列表的加法相当于extend()操作,最终的结果就是由[ ]扩充的列表。

In [22]: sum([ss.split(';') for ss in s.split('|')], [])Out[22]: ['ab', 'cd', 'efg', 'hi,jkl', 'mn\topq', 'rst,uvw\txyz']In [71]: []+['ab', 'cd']+['efg']Out[71]: ['ab', 'cd', 'efg']

综上,总的思想是,先分割一种,再分割另一种,二维降一维后,接着进行分割。我们将这个思想封装成一个接口。

In [51]: def my_split(s, seps):    ...:     res = [s]    ...:     for sep in seps:    ...:         t = []    ...:         list(map(lambda ss: t.extend(ss.split(sep)), res))    ...:         res = t    ...:    ...:     return res    ...:    ...:In [52]: my_split(s, ',;|\t')Out[52]: ['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']

这里注意个细节,res = [s],首先将字符串放进了一个列表里,是为了后面map()映射函数,作用的是列表里的整个字符串,而不是字符串里的每一个字符。这里的处理也很笼统,没有判断当前列表是否是二维,每一步都进行了降维。

------------~您没看错~这是分割线~------------

晕了吗?不慌,还有种看起来更麻烦的玩法。在此之前先来复习下reduce函数。

reduce函数对参数迭代器中的元素进行类累积

格式为:reduce(func,iter,init)

func为函数,iter为序列,init为固定初始值,无初始值时从序列的第一个参数开始

from functools import reduce# 使用reduce函数 举例:计算列表和def add(x, y) :            # 两数相加  return x + yreduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数reduce(lambda x,y:x+y,['b','c','d','e'],'a') # 'abcde'# 过程: x='a',y='b' -> 执行函数体x+y 即'a'+'b'='ab' /# 将结果给x -> x='ab',y='c' -> 执行函数体....以此类推....

reduce()+map()+sum()+str.split() 正片开始。说实话,看到这代码,真的掉头发。

In [57]: sOut[57]: 'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz'In [58]: from functools import reduceIn [59]: reduce(lambda data, sep: sum(map(lambda ss: ss.split(sep), data), []), ',;|\t', [s])Out[59]: ['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']

我们尝试着理解下,毕竟reduce、map、sum三兄弟在一起不容易啊。分解步骤,reduce()有初始值[s],即data=[s],sep=',' ,执行函数体里的内容.

In [72]: sOut[72]: 'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz'In [73]: data = [s]In [74]: sep = ','In [75]: sum(map(lambda ss: ss.split(sep), data), [])Out[75]: ['ab;cd|efg|hi', 'jkl|mn\topq;rst', 'uvw\txyz']

将运行结果重新给data,sep=';',再次执行函数体的内容。

In [76]: data = ['ab;cd|efg|hi', 'jkl|mn\topq;rst', 'uvw\txyz']In [77]: sep = ';'In [78]: sum(map(lambda ss: ss.split(sep), data), [])Out[78]: ['ab', 'cd|efg|hi', 'jkl|mn\topq', 'rst', 'uvw\txyz']

以此类推。你会发现,它将前面的知识点全部串联了起来。amazing!

当然,我们可以将其封装成一个接口。

mysplit2 = lambda s, seps:\            reduce(lambda data, sep: sum(map(lambda ss: ss.split(sep), data), []), seps, [s])print(mysplit2(s,',;|\t'))

re.split()

aa98f642-bb37-eb11-8da9-e4434bdf6706.svg

使用re模块里的split(),您会觉得 so easy~

import res = 'ab;cd|efg|hi,jkl|mn\topq;rst,uvw\txyz'# + 代表一个或者多个res = re.split('[;,|\t]+', s)print(res)# ['ab', 'cd', 'efg', 'hi', 'jkl', 'mn', 'opq', 'rst', 'uvw', 'xyz']

549e7b5245d9105641b85ed16d56ab93.png

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值