美文网首页python3 运维开发
在python3中你是如何处理字符串的?也许有你用的到的(一)

在python3中你是如何处理字符串的?也许有你用的到的(一)

作者: 运维开发_西瓜甜 | 来源:发表于2018-11-16 22:48 被阅读213次

    文本和字符串(一)


    更新信息
    2018-11-19 更新 re.split()


    分割

    split
    通过 URL 地址,得到主机名和域名

    In [41]: url = 'www.sharkyun.com'
    
    In [42]: host, domain = url.split('.', 1)
    
    In [43]: host
    Out[43]: 'www'
    
    In [44]: domain
    Out[44]: 'sharkyun.com'
    

    把下面的模块路径分隔开来,分别得到包和模块名

    # 下面是目录结构
    mod
    └── plugins
        └── cpu.py
    

    cpu.py 中有一个类

    class CPU:
        def __init__(self):
            pass
    

    我们可以这样分隔它

    plugin_path = 'mod.plugins.cpu'
    
    mod_path, cls_name = plugin.rsplit('.', 1)
    

    输出

    In [59]: mod_path
    Out[59]: 'mod.plugins'
    
    In [60]: cls_name
    Out[60]: 'cpu'
    

    也许你会遇到更为复杂的情况, 如:

    In [1]: s = 'hello xiguatian;  vars, id,def, foo'
    

    想得到所于的英文字符,之用字符串的 split() 方法是不够的,正确的是使用 re.split()

    In [2]: import re
    
    In [3]: re.split(r'[\s;,]+', s)
    Out[3]: ['hello', 'xiguatian', 'vars', 'id', 'def', 'foo']
    

    用Shell通配符匹配字符串

    如何利用 shell 里的通配符去匹配字符串,比如用 *.log 去匹配 access.log 等。
    fnmatch 模块提供了两个函数—— fnmatch()fnmatchcase() ,可以用来实现这样的匹配。
    用法如下:

    In [3]: fnmatch('cpu.py', '*.py')
    Out[3]: True
    
    In [4]: fnmatch('cpu.py', '?pu.py')
    Out[4]: True
    
    In [5]: fnmatch('data10.py', 'data[0-9][0-9].py')
    Out[5]: True
    

    fnmatch() 函数在类 linux 平台中是区分大小写的,而在 Windows 下是不区分的.

    # On OS X (Mac)
    In [6]: ffnmatch('foo.txt', '*.TXT')
    Out[6]: False
    # On Windows
    In [7]: ffnmatch('foo.txt', '*.TXT')
    Out[7]: True
    

    fnmatchcase() 函数可以绝对的区分大小写

    In [14]: fnmatchcase('foo.txt', '*.TXT')
    Out[14]: False
    

    注意:上面的第一个参数,对于这两个函数只是字符串而已,python 不会判断是否是文件名。所以你若是相对文件名做匹配,请使用 glob 模块。

    假如有如下大学信息

    star_rating = [
        "北京大学 8星级",
        "清华大学 8星级",
        "中国人民大学 8星级",
        "北京师范大学 6星级",
        "北京航空航天大学 6星级",
        "北京理工大学 5星级",
        "中国农业大学 6星级",
        "北京交通大学 4星级",
        "北京科技大学 4星级",
        "北京协和医学院 6星级"
    ]
    

    找到 6 到 8 星级的大学

    university = [star for star in star_rating if fnmatchcase(star, '*[6-8]星级') ]
    
    print(university)
    

    输出结果

    ['北京大学 8星级', 
     '清华大学 8星级', 
    '中国人民大学 8星级',
     '北京师范大学 6星级', 
    '北京航空航天大学 6星级',
     '中国农业大学 6星级', 
    '北京协和医学院 6星级'
    ]
    

    搜索替换

    replace()

    s = "shark www.sharkyun.com"
    
    # 把 shark 换成 xiguatian
    s = s.replace('shark', 'xiguatian')
    

    输入结果

    print(s)
    xiguatian www.xiguatianyun.com
    

    当然,事情往往不总是都是那么多称心如意。比如:
    将形式为 11/16/2018 的日期字符串改成 2018-11-16
    这时候,就要使用杀手锏正则模块 re
    re 模块中的 sub() 函数可以为我们办的。代码如下:

    import re
    
    text = 'Today is 11/16/2018.'
    
    re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text)
    

    输出结果

    'Today is 2018-11-16.'
    

    \1 \2 \3 是对前面小括号内模式的匹配结果的都捕获,就是分组。

    如果有个正则的模式可能需要多次使用,那就要考虑先编译它来提升性能。

    import re
    
    datepat = re.compile(r'(\d+)/(\d+)/(\d+)')
    datepat.sub(r'\3-\1-\2', text)
    

    假如,想知道有多少替换发生了,可以使用 re.subn() 来代替。比如:

    In [31]: text = 'Today is 11/16/2018.'
    
    In [32]: new_text, n = re.subn(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text)
    
    In [33]: new_text
    Out[33]: 'Today is 2018-11-16.'
    
    In [34]: n
    Out[34]: 1
    

    更加复杂的替换需求:把其中的月份 11 改为 Nov
    预备知识:

    In [47]: from calendar import month_abbr
    
    In [48]: month_abbr[1]
    Out[48]: 'Jan'
    
    In [49]: month_abbr[11]
    Out[49]: 'Nov'
    

    month_abbr 是一个可被迭代对对象,里面存放了 12 个月份的英文3个字母的缩写, 第一个位置为空的字符串 '', 我们可以通过索引号1-12进行分别取值。

    开始正题:
    更加复杂的替换,可以传递一个替换回调函数给 sub() 函数。

    import re
    from calendar import month_abbr
    
    text = 'Today is 11/16/2018.'
    
    def change_date(m):
        mon_name = month_abbr[int(m.group(1))]
        return '{} {} {}'.format(m.group(2), mon_name, m.group(3))
    
    new_text = re.sub(r'(\d+)/(\d+)/(\d+)', change_date, text)
    

    输出结果

    print(new_text)
    Today is 16 Nov 2018.
    

    替换回调函数的参数是一个 match 对象,也就是 match()返回的对象。
    这里我接着使用 group() 方法来提取特定的匹配部分。
    回调函数最后返回替换后的字符串。

    相关文章

      网友评论

        本文标题:在python3中你是如何处理字符串的?也许有你用的到的(一)

        本文链接:https://www.haomeiwen.com/subject/mtjpfqtx.html