1. 分割字符串-使用多个界定符【re.split()】

>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

string 对象的 split() 方法只适应于非常简单的字符串分割情形, 它并不允许有多个分隔符或者是分隔符周围不确定的空格。 当你需要更加灵活的切割字符串的时候,最好使用 re.split() 方法

>>> fields = re.split(r'(;|,|\s)\s*', line)
>>> fields
['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']
>>>

如果re.split()中使用了括号捕捉分组。如果使用了括号,那么被匹配的文本也将出现在结果列表中。

如果不想保留分割字符串到结果列表中去,但仍然需要使用到括号来分组正则表达式的话, 确保你的分组是非捕获分组,形如 (?:...) 。比如

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

2. 字符串的开头匹配或结尾匹配【str.startwith()或 str.endwith()】

如果想匹配多种可能时.只需将所有的匹配项放入到一个元组【tuple】中然后传给str.startwith()或 str.endwith()中

>>> filenames
[ 'Makefile', 'foo.c', 'bar.py', 'spam.c', 'spam.h' ]
>>> [name for name in filenames if name.endswith(('.c', '.h')) ]
['foo.c', 'spam.c', 'spam.h']

3. 用Shell通配符匹配字符串--【fnmath模块提供的两个函数--fnmatch()和fnmatchcase()】

Unix Shell 中常用的通配符(比如 *.py , Dat[0-9]*.csv 等)去匹配文本字符串

#  Shell通配符
#
# ? 任意单个字符
# * 任意0个或多个字符
# [ ] 匹配方括号中的任意一个字符,如[abc] 则匹配abc中的一个
# [ - ] "-"代表范围,例如:[a-z] 则匹配任意一个小写字母; [0-9] 则匹配任意一个0-9之间的数据,但是注意[0-10]不可以,不能超过9
# [^] 逻辑非. 例如: [^0-9]匹配任意一个非数字字符
>>> from fnmatch import fnmatch, fnmatchcase
>>> fnmatch('foo.txt', '*.txt')
True
>>> fnmatch('foo.txt', '?oo.txt')
True
>>> fnmatch('Dat45.csv', 'Dat[0-9]*')
True
>>> names = ['Dat1.csv', 'Dat2.csv', 'config.ini', 'foo.py']
>>> [name for name in names if fnmatch(name, 'Dat*.csv')]
['Dat1.csv', 'Dat2.csv']

fnmatch() 函数使用底层操作系统的大小写敏感规则(不同的系统是不一样的)来匹配模式。比如:

>>> # On OS X (Mac)
>>> fnmatch('foo.txt', '*.TXT')
False
>>> # On Windows
>>> fnmatch('foo.txt', '*.TXT')
True
>>>

如果你对这个区别很在意,可以使用 fnmatchcase() 来代替。它完全使用你的模式大小写匹配。

常用场景:在处理非文件名的字符串时候它们也是很有用的。文件名的匹配,最好使用 glob 模块

addresses = [
'5412 N CLARK ST',
'1060 W ADDISON ST',
'1039 W GRANVILLE AVE',
'2122 N CLARK ST',
'4802 N BROADWAY',
]
你可以像这样写列表推导: >>> from fnmatch import fnmatchcase
>>> [addr for addr in addresses if fnmatchcase(addr, '* ST')]
['5412 N CLARK ST', '1060 W ADDISON ST', '2122 N CLARK ST']
>>> [addr for addr in addresses if fnmatchcase(addr, '54[0-9][0-9] *CLARK*')]
['5412 N CLARK ST']
>>>

4. 字符串匹配和搜索

如果你想匹配的是字面字符串,那么你通常只需要调用基本字符串方法就行, 比如 str.find() , str.endswith() , str.startswith() 或者类似的方法:

 对于复杂的匹配需要使用正则表达式和 re 模块。 为了解释正则表达式的基本原理,假设你想匹配数字格式的日期字符串比如 11/27/2012 ,你可以这样做

>>> text1 = '11/27/2012'
>>> text2 = 'Nov 27, 2012'
>>>
>>> import re
>>> # Simple matching: \d+ means match one or more digits
>>> if re.match(r'\d+/\d+/\d+', text1):
... print('yes')
... else:
... print('no')
...
yes
>>> if re.match(r'\d+/\d+/\d+', text2):
... print('yes')
... else:
... print('no')
...
no
>>>

如果你想使用同一个模式去做多次匹配,你应该先将模式字符串预编译为模式对象。比如:

>>> datepat = re.compile(r'\d+/\d+/\d+')
>>> if datepat.match(text1):
... print('yes')
... else:
... print('no')
...
yes
>>> if datepat.match(text2):
... print('yes')
... else:
... print('no')
...
no
>>>

match() 总是从字符串开始去匹配,如果你想查找字符串任意部分的模式出现位置, 使用 findall() 方法去代替。比如:

>>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
>>> datepat.findall(text)
['11/27/2012', '3/13/2013']
>>>

在定义正则式的时候,通常会利用括号去捕获分组。

#在定义正则式的时候,通常会利用括号去捕获分组
#捕获分组可以使得后面的处理更加简单,因为可以分别将每个组的内容提取出来
>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)')
>>> m = datepat.match('11/27/2012')
>>> m
<_sre.SRE_Match object at 0x1005d2750>
>>> # Extract the contents of each group
>>> m.group(0)
'11/27/2012'
>>> m.group(1)
''
>>> m.group(2)
''
>>> m.group(3)
''
>>> m.groups()
('', '', '')
>>> month, day, year = m.groups()
>>>
>>> # Find all matches (notice splitting into tuples)
>>> text
'Today is 11/27/2012. PyCon starts 3/13/2013.'
>>> datepat.findall(text)
[('', '', ''), ('', '', '')]
>>> for month, day, year in datepat.findall(text):
... print('{}-{}-{}'.format(year, month, day))
...
2012-11-27
2013-3-13
>>>

正则表达式步骤: re.compile()编译正则表达式字符串, 然后使用match(), findall(), finditer()等方法

如果你想精确匹配,确保你的正则表达式以$结尾,就像这么这样:

>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)$')
>>> datepat.match('11/27/2012abcdef')
>>> datepat.match('11/27/2012')
<_sre.SRE_Match object at 0x1005d2750>
>>>

最后,如果你仅仅是做一次简单的文本匹配/搜索操作的话,可以略过编译部分,直接使用 re 模块级别的函数。比如:

>>> re.findall(r'(\d+)/(\d+)/(\d+)', text)
[('', '', ''), ('', '', '')]
>>>

2.5 字符串搜索和替换

对于简单的字面模式,直接使用 str.replace() 方法即可,比如:str.replace('tihuan_qian', 'tihuan_hou')

复杂的模式,使用re模块的sub()函数。

例: 11/27/2012 的日期字符串改成 2012-11-27

>>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
>>> import re
>>> re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text)
'Today is 2012-11-27. PyCon starts 2013-3-13.'
>>>

sub() 函数中的第一个参数是被匹配的模式,第二个参数是替换模式。反斜杠数字比如 \3 指向前面模式的捕获组号。

 如果你打算用相同的模式做多次替换,考虑先编译它来提升性能。比如:
>>> import re
>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)')
>>> datepat.sub(r'\3-\1-\2', text)
'Today is 2012-11-27. PyCon starts 2013-3-13.'
result, n  = re.subn(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text)

re.subn()可以知道替换次数

 

python3: 字符串和文本的更多相关文章

  1. [转]python3字符串与文本处理

    转自:python3字符串与文本处理 阅读目录 1.针对任意多的分隔符拆分字符串 2.在字符串的开头或结尾处做文本匹配 3.利用shell通配符做字符串匹配 4.文本模式的匹配和查找 5.查找和替换文 ...

  2. python3字符串与文本处理

    每个程序都回涉及到文本处理,如拆分字符串.搜索.替换.词法分析等.许多任务都可以通过内建的字符串方法来轻松解决,但更复杂的操作就需要正则表达式来解决. 1.针对任意多的分隔符拆分字符串 In [1]: ...

  3. python3: 字符串和文本(4)

    16. 以指定列宽格式化字符串[textwrap] https://docs.python.org/3.6/library/textwrap.html#textwrap.TextWrapper 假如你 ...

  4. python3: 字符串和文本(3)

    11. 删除字符串中不需要的字符  strip() 方法能用于删除开始或结尾的字符: lstrip() 和 rstrip() 分别从左和从右执行删除操作 >>> s = ' hell ...

  5. python3: 字符串和文本(2)

    6. 字符串忽略大小写的搜索替换 >>> text = 'UPPER PYTHON, lower python, Mixed Python' >>> re.find ...

  6. Python3-Cookbook总结 - 第二章:字符串和文本

    第二章:字符串和文本 几乎所有有用的程序都会涉及到某些文本处理,不管是解析数据还是产生输出. 这一章将重点关注文本的操作处理,比如提取字符串,搜索,替换以及解析等. 大部分的问题都能简单的调用字符串的 ...

  7. Python3 批量替换文本内容

    Python3 批量替换文本内容 示例: # coding:utf8 import os; def reset(): i = 0 path = r"H:\asDemo\workdemo\aw ...

  8. 《Python CookBook2》 第一章 文本 - 过滤字符串中不属于指定集合的字符 && 检查一个字符串是文本还是二进制

    过滤字符串中不属于指定集合的字符 任务: 给定一个需要保留的字符串的集合,构建一个过滤函数,并可将其应用于任何字符串s,函数返回一个s的拷贝,该拷贝只包含指定字符集合中的元素. 解决方案: impor ...

  9. python3字符串

    Python3 字符串 Python字符串运算符 + 字符串连接 a + b 输出结果: HelloPython * 重复输出字符串 a*2 输出结果:HelloHello [] 通过索引获取字符串中 ...

随机推荐

  1. 13.Promise 对象

    Promise 对象 Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大.它由社区最早提出和实现,ES6 将其 ...

  2. Jquery Easy UI初步学习(三)数据增删改

    第二篇只是学了加载用datagrid加载数据,数据的增删改还没有做,今天主要是解决这个问题了. 在做增删改前需要弹出对应窗口,这就需要了解一下EasyUi的弹窗控件. 摘自:http://philoo ...

  3. SpringBoot(八) Caching (更新中...)

    缓存配置 在springboot的主类添加注解@EnableCaching启用缓存支持 参考文档 33. Caching spring framework >>> 8. Cache ...

  4. java并发编程的艺术(二)---重排序与volatile、final关键字

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  5. JVM之---Java源码编译机制

    Sun JDK中采用javac将Java源码编译为class文件,这个过程包含三个步骤:     1.分析和输入到符号表(Parse and Enter)    Parse过程所做的工作有词法和语法分 ...

  6. Mac下 KGDB连接Linux

    kgdb按照资料说可以使用网络(kgdboe)和串口连接(kgdboc)等方式连接. 这里使用后者,资料比较多,下面是自己在Mac上进行配置连接的过程. 先说一下环境: 主机:Mac OSX 10.1 ...

  7. java-接口和抽象类的联系和区别。

    接口和抽象类的联系和区别. 一,简单总结 1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象. 2.抽象类要被子类继 ...

  8. package.json中devDependencies与dependencies的区别

    前言:之前一直不懂既然都是项目的依赖,为什么要分成两个部分,devDependencies和dependencies,有什么区别? 安装方式 我们在通过npm安装插件或库时,有三种方式: npm in ...

  9. html active属性

    源代码 <div class="col-md-3"> <div class="list-group"> <a href=" ...

  10. [转]XSS的原理分析与解剖:第四章(编码与绕过)

    0×01前言 很抱歉,这第四章被我推了几个月,今天是元旦难得有空,就把第四章写下.我先把主要使用的编码说下,介绍完会说下绕过. 本文建议与<杂谈如何绕过WAF>一同阅读. 0×02 URL ...