zoukankan      html  css  js  c++  java
  • 字符串和文本

    一、对任意多的分隔符拆分字符串

      字符串对象的split()方法只能处理非常简单的情况,而且不支持多个分隔符,对分隔符周围可能存在的空格也无能为力。

      应该使用 re.split(),需要小心正则表达式模式中的捕获组(capture group)是否包含在了括号中。

      如果用到了捕获组,那么匹配的文本也会包含在最终结果中。

    >>> line = 'asdf fkdk; afed, fdsf,asdf,   foo'
    >>> re.split(r'[;,s]s*',line)
    ['asdf', 'fkdk', 'afed', 'fdsf', 'asdf', 'foo']
    
    >>> re.split(r'(;|,|s)s*',line)
    ['asdf', ' ', 'fkdk', ';', 'afed', ',', 'fdsf', ',', 'asdf', ',', 'foo']

      如果不想再结果中看到分割字符,但仍想用括号来对正则表达式模式进行分组确保用的是非捕获组,以(?: )的形式指定。

    >>> re.split(r'(?:;|,|s)s*',line)
    ['asdf', 'fkdk', 'afed', 'fdsf', 'asdf', 'foo']

    二、在字符串的开头或结尾处做文本匹配

      使用str.startswith()和str.endswith()方法。

      如果需要同时对多个选项做检查,只需给startswith()和endswitch()提供包含可能选项的元组 即可!

      >>> [name for name in filenames if name.endswith(('.c','.h')) ]

      使用re正则表达式作为替代方案:

      >>> re.match(r'http:|https:|ftp:|', url)

      检查目录有无出现特定文件:

      >>> if any(name.endswith(('.c','.h')) for name in listdir(dirname)):

    三、利用Shell通配符做字符串匹配

      fnmatch模块提供两个函数,fnmatch()和fnmatchcase(),可用来执行这样的匹配。使用起来更加简单:

    >>> from fnmatch import fnmatch,fnmatchcase
    >>> fnmatch('foo.txt','*.txt')
    >>> fnmatch('foo.txt','?oo.txt')
    True
    >>> fnmatch('Dat45.csv','Dat[0-9]*')
    True
    >>> fnmatchcase('foo.txt','*.TXT')
    False

      fnmatch()的匹配模式所采用的大小写区分规则和底层文件系统相同(根据操作系统的不同而有所不同)。

      使用fnmatchcase()。完全根据提供的大小写方式来匹配

    四、文本模式的匹配和查找

      如果要匹配的是简单文字,只需要使用基本的字符串方法就可以了,如:str.find()、str.endswith()、str.startswith()或类似的函数。

      复杂匹配使用正则表达式以及re模块。

      re.match()方法总是尝试在字符串的开头找到匹配项。

      如果想针对整个文本搜索出所有的匹配项,那么就应该使用findall()方法。

      当定义正则表达式时,用括号抱起来的方式引入捕获组,能简化对匹配文本的处理。

      每个组的内容都可以单独提取出来。

      finditer()方法,以迭代的方式找出匹配项。

    五、查找和替换

      简单文本使用:str.replace()即可。复杂模式使用re.sub()函数。

      例子:将9/10/2019格式改为2019-9-10。

    >>> text = 'Today i 9/10/2019  Pycon start 3/13/2013'
    >>> import re
    >>> re.sub(r'(d+)/(d+)/(d+)',r'3-1-2-',text)
    'Today i 2019-9-10-  Pycon start 2013-3-13-'

      对于更加复杂的文本,可以指定一个替换回调函数

    datepat = re.compile(r'(d+)/(d+)/(d+)')
    from calendar import month_abbr
    def change_date(m):
        mon_name = month_abbr[int(m.group(0))]
        return '{} {} {}'.format(m.group(2), mon_name, m.group(1))
    datepat.sub(change_date, text)

      替换回调函数的输入参数是一个匹配对象,由match()或find()返回。

      用.group()方法来提取匹配中特定的部分。这个函数应该返回替换后的文本。

      除了得到替换后文本外,还想知道一共完成了多少次替换,可以使用re.subn()。

    六、不区分大小写的方式对文本做查找和替换

      使用re模块加上re.IGNORECASE标记。

      使用支撑函数,修正待替换文本和匹配文本大小写不吻合情况。

    def matchcase(word):
        def replace(m):
            text = m.group()
            if text.isupper():
                return word.upper()
            elif text.islower():
                return word.lower()
            elif text[0].isupper():
                return word.capitalize()
            else:
                return word
        return replace
    
    re.sub('python',matchcase('snake'),text,flags=re.IGNORECASE)

    七、实现最短匹配的正则表达式

      *操作符在正则表达式中采用贪心策略,所以匹配过程是基于找出最长的可能匹配来进行的。

      只要在*操作符后面加上 ?修饰符就可以了。

    >>> text1 = 'Computer says "no." phone says "yes."'
    >>> re.findall(r'"(.*)"',text1)
    ['no." phone says "yes.']
    >>> re.findall(r'"(.*?)"',text1)
    ['no.', 'yes.']

    八、多行模式的正则表达式

      .句点并不能匹配换行符。需要添加对换行符的支持

    >>> comment = re.compile(r'/*(.*?)*/')
    >>> comment = re.compile(r'/*((?:.|
    )*?)*/')

      (?:.| ),指定了一个非捕获组(即,这个组只做匹配但不捕获结果,也不会分配组号)

      也可以直接使用re.DOTALL模式,句点符号将匹配所有的字符。  

    九、将unicode文本统一表示为规范形式

      >>> t1 = unicodedata.normalize('NFC', s1)

      >>> t2 = unicodedata.normalize('NFD', s1)

    十、正则表达式处理Unicode字符

      能在多个不同的阿拉伯代码页中匹配所有的字符:

      >>> arabic = re.compile('[u0600-u06ffu0750-u077fu08a0-u08ff]+ ')

    十一、从字符串中去掉不需要的字符

      在字符串的开始、结尾、中间去掉不需要的字符。

      strip()可用来从字符串的开始、结尾处去掉字符;lstrip()和rstrip()可分别从左或者右侧开始执行去掉字符的操作。

      默认情况下这些方法去除的是空格符,但也可以指定其他字符。

    with open(filename) as f:
        lines = (line.strip() for line in f)
        for line in lines:
            ...

    十二、文本过滤和清理

      (1)建立一个转换表,然后使用translate()方法;

    remap = {
        ord('	') : ' ',
        ord('f') : ' ',
        ord('
    ') : None,
    }
    
    a = s.translate(remap)

      (2)对文本能做初步的清理,然后结合encode()和decode()操作来修改或清理文本;

    t1 = unicodedata.normalize('NFD', s1)
    t1.encode('ascii', 'ignore').decode('ascii')

    十三、对齐文本字符串

      (1)使用字符串的ljust()、rjust()、center()方法。所有这些方法都可以接受一个可选的填充字符。

    >>> text.ljust(20,'=')
    'Hello World========='

      (2)format(),函数也可以用来完成对齐的任务,合理使用< > ^以及一个期望的宽度值。

      >>> format(text, '>20')

      >>> format(text, '*^20s')

      >>> '{:>10s} {:>10s}'.format('Hello', 'World')

      format好处在于并不特定于字符串,还可以对数字做格式化处理:

      >>> format(1.2345, '>10')

      >>> format(1.2345, '^10.2f')

    十四、字符串连接及合并

      合并使用join()、+操作符或者直接排列一起,中间不加操作符;

      复杂场景用format。

      +操作符做链接非常低效,在于内存拷贝和垃圾收集产生的影响。每个+=操作符都会创建一个新的字符串对象。

      利用生成器技巧:

      >>> data = ['ACME', 50, 902]

      >>> ','.join(str(d) for d in data)

      打印时连接操作:

      >>> print(a + ':' + b + ':' + c)

      >>> print(':'.join([a, b, c]))

      >>> print(a, b, c, sep=':')

      同I/O操作混合使用:

    def combine(source, maxsize):
        parts = []
        size = 0
        for part in source:
            parts.append(part)
            size += len(part) 
            if size < maxsize:
                yield ''.join(parts)
                parts = []
                size = 0
        yield ''.join(parts)
    
    for part in combine(sample(), 32876):
        f.write(part)

    十五、字符串中的变量名做插值处理

      创建一个字符串,其中嵌入的变量名称会以变量的字符串值形式替换掉。Python并不会直接支持在字符串中对变量做简单的值替换

      (1)使用format()方法。

      >>> s = '{name} has {n} message'

      >>> s.format(name='David', n=33)

      (2)format_map()和vars联合使用。vars还可以用于实例上。

      >>> s.format_map(vars())

      >>> s.format_map(vars( Info('David',37) ))  

      (3)format和format_map缺点,无法处理缺省值。单独定义__missing__()方法的字典类

    class safesub(dict):
        def __missing__(self):
            return '{' + key +'}'
    
    s.format_map(safesub(vars()))
    'David has {n} message'

    十六、以固定列数重新格式化文本

      使用textwrap 模块

      >>> print(textwrap.fill(s, 40))

      os.get_terminal_size().columns 来获取终端尺寸大小。

    十七、在文本中处理HTML和XML实体

      将&entity或&#code这样的HTML或XML实体替换为它们相对应的文本。

      或者我们需要生成文本,但是要对特定的字符做转义处理。

      >>> s =  'as dafsd  "<tag>Hello world</tag>"  asd'

      (1)生成文本,使用html.escape(s, quote=False)

      # as dafsd  "&lt;tag&gt;Hello world&lt;/tag&gt;"  asd'

      (2)替换实体 HTML:

      >>> from html.parser import HTMLParser

      >>> p = HTMLParser()

      >>> p.unescape(s)

      (3)替换实体 XML:

      >>> from xml.sax.saxutils import unescape

      >>> unescape(t)

      

    二十、在字节串上执行文本操作

      在字节串(Byte String)上执行常见的文本操作,拆分、搜索和替换。

      特别的需要在正则模式上做处理需要指定字节串的形式。

      >>> re.split(b'[:,]', data)

      print输出区别:

    >>> a = 'Hello World'
    >>> a[0]
    'H'
    >>> a[1]
    'e'
    >>> b = b'Hello World'
    >>> b[0]
    72
    >>> b[1]
    101

      字节串上没有格式化操作。

  • 相关阅读:
    深入探索 高效的Java异常处理框架
    Java多线程调试如何完成信息输出处理
    WebKit学习资源
    WebKit阅读起步
    Redis学习资源
    webkit在vs2008中编译
    【转】推荐几本学习MySQL的好书-MySQL 深入的书籍
    Mysql: 开启慢查询日志[ERROR] unknown variable 'log-slow-queries'处理办法
    Linux top命令详解
    eclipse svn同步过滤掉某些不需要同步的文件
  • 原文地址:https://www.cnblogs.com/5poi/p/11495377.html
Copyright © 2011-2022 走看看