Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

使用Python进行文本处理

6
Jan
2012

使用Python进行文本处理

By Alex
/ in Python
/ tags 文本处理
0 Comments
编程语言特性
字符串的表示

在Python2中,类型 str 和 unicode 分别用于表示单字节字符串和Unicode字符串;在Python3中,所有字符串都使用Unicode表示,类型为str。

字符串可以使用单引号、双引号、三引号包围, 三引号中的字符串原样保留,可以方便的编写多行文本。

字符串的引号开始前,可以增加 u 、 r 修饰符,分别表示目标字符串是Unicode类型、不启用字符转义。

Python没有单独的字符类型,字符只是长度为1的字符串

切片运算符

在Python语言中,字符串属于(不可变)序列,支持有限的切片操作:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
s = "一二三四五六七"
# 取子串,起始索引包含,结束索引不包含
assert s[1:3] == '二三'
assert s[-3:] == '五六七'
i = 3
assert s[:i] + s[i:] == s
 
# 带步进的切片,默认1,即下一个元素的索引比上一个大1
assert s[1:4:1] == '二三四'
assert s[1:4:2] == '二四'
assert s[1:4:3] == '二'
# 负数的步进,下面这个用于生成倒序的串
assert s[::-1] == '七六五四三二一'
assert s[4:1:-1] == '五四三'
in运算符

在Python中,此操作符可以用于成员关系测试,或者迭代:

Python
1
2
3
s = '01234567'
assert '3' in s
for c in s: print(c)
+和*运算符

适用于任意切片的运算符还包括 + 和 * ,分别可以用于连接、重复字符串:

Python
1
2
assert '123' + '4567' == '1234567'
assert '123' * 3 == '123123123'
内置函数与方法

很多内置函数、方法可以用于操控字符串: 

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
s = "01234567"
# 计算序列长度
assert len(s) == 8
# 获取序列元素的最小值
assert min(s) == '0'
# 获取序列元素的最大值
assert max(s) == '7'
 
# 查找,获得子串的索引,两个方法类似,但是index()在无法子串不存在时抛出ValueError
assert s.index('67') == 6
assert s.find('67') == 6
# 查找,子串判断
assert s.startswith('012') and s.endswith('4567')
# 替换,注意字符串是不可变的,因此返回的是副本
assert s.replace('3', 'x') == "012x4567"
# 分割
assert s.split('3') == ['012', '4567']
# 连接
assert ','.join(['1', '2', '3']) == '1,2,3'
# 对齐和填充
assert s.ljust(10, '0') == '0123456700'
# 去除空白,左侧
assert s.lstrip('0') == '1234567'
# 特性检查:is*()方法
assert s.isalnum()  # 是否仅包含字母数字
字符串格式化

Python支持两种风格的字符串格式化操作,包括旧式的 % 操作符,以及新式的 format() 方法。

基于%操作符的格式化

可以使用 % 操作符来进行字符串格式化, s % d 左侧为格式模板,右边为占位符元组或字典,这与C语言的sprintf()函数类似。一个简单的例子如下:

Python
1
2
'%s %s' % ('one', 'two') 
'%(k1)s %(k2)s' % {'k1':'one','k2':'two'}

格式模板由普通字符、转换说明符组成,转换说明符以%开头,具体含义如下:

 格式说明符 输出格式 
d, i  十进制整数、长整数
u 无符号整数、长整数
o 八进制整数、长整数
x 十六进制整数、长整数
X 十六进制整数(大写字母)
f 浮点数,如[-]m.dddddd
e 浮点数,如[-]m.dddddde+xx
E 浮点数,如[-]m.ddddddE+xx
g, G 指数小于-4或更高精度时使用%e或%E,否则格式化为浮点数
保留N位有效数字,N为下表的修饰符字段,采取四舍五入方式
s 字符串或任意对象。格式化代码使用str()生成字符串
r 同repr ()生成的字符串
c 单个字符
% 字面值%

在字符%与上表列出的转换字符之间,可以按顺序出现以下修饰符:

 修饰符  说明
(KEY) 表示从字典中取值的键
- 左对齐标志位,默认右对齐
+ 保留数字的符号(即使正数)
0 表示一个零填充
M 表示输出的最小宽度
. 小数点,用于按精度分割字段宽度
N 要打印字符串的最大字符数、浮点数小数点后的位数、整数的最小位数
* 从元组中读取字段的宽度数字
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a = 42
b = 13.142783 c = "hello"
d = {'x':13, 'y':l.54321, 'z':'world'}
e = 5628398123741234
 
r = "a is %d" % a                     # r = "a is 42"
r = "%10d %f" %(a,b)                  # r = "        42 13.142783"    整数宽度10,右对齐
r = "%+010d %E" %(a,b)                # r = "+000000042 1.314278E+01" 整数宽度10,右对齐,不足补0
r = "%(x)-10d %(y)0.3g" % d           # r = "13          1.54"        从字典d里取出值并对其执行转换
r = "%0.4s %s" %(c, d['z'])           # r = "hell world"              第一个字符串最大打印长度为4
r = "%*.*f" % (5,3,b)                 # r = "13.143"                  元组的前两项作为格式字符串的组成部分
 
#注意,格式化字符串与字典一起使用,行为类似于字符串插值:
p = {'age' : 28, 'name' : 'Alex'}
r = "%(name)s's age is %(age)d" % p   # r = "Alex's age is 28"
基于string.format()方法的格式化

通过调用作为模板的字符串的format()是Python新式的格式化机制。模板由普通字符和占位符组成,可以使用 {place:format_spec} 的形式来声明一个占位符,它包括两个部分:

  1. place,位置,可以是数字表示的位置参数、标识符表示的命名参数。默认情况下Python使用 __format__() 得到对象的文本表示,要改变此行为,可以扩展place为 place!type 形式。其中type可以取值s、r、a,分别调用 __str__() 、 __repr__() 和 ascii() 完成文本转换,a仅在Python3中被支持
  2. format_spec,格式说明符,形式为: [[fill]align][sign][#][0][width][,][.precision][type] ,各字段说明如下:
fill 当指定align时,可以指定该字段,用于补白,默认空格
align

对齐方式: < 表示左对齐, > 表示右对齐, = 表示在数字左侧补白, ^ 表示居中对齐

sign 符号,可以取值 + 、 - 和空格
# 仅用于二、八、十六进制,如果出现此符号,输出分别添加前缀 0b 、 0o 、 0x 
, 千位分隔符
width 指定最小宽度
precision 使用f或者F格式化时,小数的位数
使用g或者G格式化时,数字的位数
对于非数字,表示最大字符数
不可用于整数
type 格式化为什么类型,参考上文“格式说明符”

代码示例:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# ###  参数占位符  ###
# 位置参数
'{0}, {1}, {2}'.format('a', 'b', 'c')  # 'a, b, c'
'{2}, {1}, {0}'.format('a', 'b', 'c')  # 'c, b, a'
'{}, {}, {}'.format('a', 'b', 'c')  # 'a, b, c' 要求2.7+
'Hello {0}'.format('Alex') == 'Hello Alex'
# 命名参数
'Coordinates: {latitude}, {longitude}'.format(latitude = '37.24N', longitude = '-115.81W')
'Hello {name}'.format(name = 'Alex') == 'Hello Alex'
# 访问对象属性
person = lambda: None
person.greeting = 'Hello'
person.name = 'Alex'
assert '{0.greeting} {0.name}'.format(person) == 'Hello Alex'
# 访问序列的元素
coord = (3, 5)
'X: {0[0]};  Y: {0[1]}'.format(coord)
 
# ###  格式控制  ###
# 对齐和填充
'{:>30}'.format('right aligned')  # '                 right aligned'
'{:*^30}'.format('centered')  # '***********centered***********'
# 浮点数
'{:+f}; {:+f}'.format(3.14, -6.02)  # '+3.140000; -6.020000'
# 千分位
'{:,}'.format(1234567890)  # '1,234,567,890'
 
# 格式化时间
import datetime
d = datetime.datetime(2010, 7, 4, 12, 15, 58)
'{:%Y-%m-%d %H:%M:%S}'.format(d)  # '2010-07-04 12:15:58'
正则表达式

re模块可以用于正则表达式的处理。

正则式字符序列
字符序列 说明
text 匹配文字字符串text
. 匹配任何字符串,但换行符除外
^ 匹配字符串的开始
$ 匹配字符串的结束
* 匹配前面表达式的0个或多个副本,匹配尽可能多的副本
+ 匹配前面表达式的1个或多个副本,匹配尽可能多的副本
? 匹配前面表达式的0个或多个副本,匹配尽可能多的副本
*? 匹配前面表达式的0个或多个副本,匹配尽可能少的副本
+? 匹配前面表达式的1个或多个副本,匹配尽可能少的副本
?? 匹配前面表达式的0个或多个副本,匹配尽可能少的副本
{m} 准确匹配前面表达式的m个副本
{m, n} 匹配前面表达式的第m到n个副本,尽可能匹配多的副本
{m, n}? 匹配前面表达式的第m到n个副本,尽可能匹配少的副本
[...] 匹配一组字符,如 r'[abcde]' 或者 r'a-zA-Z' 
[^...] 匹配集合中未包含的字符,如 r'[^0-9]' 
A|B 匹配A或者B,A和B都是正则式
(...) 匹配圆括号中的正则表达式(圆括号中的内容为一个分组)并保存匹配的子字符串
在匹配时,分组中的内容可以使用所获得的 MatchObject 对象的 group() 方法获取
(?aiLmsux) 把字符解释为对应的标记位,例如i表示无视大小写
(?:...) 匹配圆括号中的正则表达式,但丢弃匹配的子字符串
(?P<name>...) 匹配圆括号中的正则表达式并创建一个命名(named)分组。分组名称必须是有效的Python标识符
(?P=name) 引用命名分组:匹配一个前面指定的分组所匹配的文本
(?#...) 一个注释。圆括号中的内容将被忽略
(?=...) 只有在括号中的模式匹配时,才匹配前面的表达式。例如 'Hello(?=World)' 只有在 World 匹配时才匹配 Hello 
(?!...) 只有在括号中的模式不匹配时,才匹配前面的表达式
(?<=...) 如果括号后面的表达式前面的值与括号中的模式匹配,则匹配该表达式。例如,只有当 'def' 前面是 'abc' 时, r'(?<=abc)def' 才会与它匹配
(?<!...) 如果括号后面的表达式前面的值与括号中的模式不匹配,则匹配该表达式
\number 引用序号分组:匹配与前面的组编号匹配的文本。组编号范围为1到99,从左侧开始为组编号
\A 仅匹配字符串的开始标志
\b 匹配单词开始或结尾处的空字符串。单词是一个字母数字混合的字符序列,以空格或任何其他非字母数字字符结束
\B 匹配不在单词开始或结尾处的空字符串
\d 匹配任何十进制数。等同于 r'[0-9]' 
\D 匹配任何非数字字符。等同于 r'[^0-9]' 
\s 匹配任何空格字符。等同于 r'[\t\n\r\f\v] 
\S 匹配任何非空格字符,等同于 r'[^\t\n\r\f\v] 
\w 匹配任何字母数字字符
\W 匹配\w定义的集合中不包含的字符
\z 仅匹配字符串的结束标志
\\ 匹配反斜杠本身
 应用举例
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import re
#获取字符串中与模式匹配的所有不重叠值,包括空匹配
#如果模式包含分组,将返回与分组匹配的文本列表,如果包含多个分组,则前述列表的每一项都是一个元组
#finditer与之类似,但是返回的是MatchObject的迭代器
#(\D+)(\d+) 结果:[('a', '0'), ('b', '12'), ('c', '345'), ('d', '6789')]
#(\D+)\d+   结果:['a', 'b', 'c', 'd']
#\D+\d+     结果:['a0', 'b12', 'c345', 'd6789']
m = re.findall(r'\D+\d+', 'a0b12c345d6789', re.IGNORECASE)  # 由于正则式特殊字符很多,故一般使用“原始字符串”
print m
 
r = re.compile(r'\D+\d+', re.IGNORECASE)       #编译得到一个正则式对象
#search()、match()返回MatcherObject对象
 
 
s = 'Iggle Piggle and Makka    Pakka are in the night garden'
# match、search等方法返回MatchObject:
# group(n):返回匹配中第n个分组,如果n==0或者为空,返回整个匹配
 
 
# match函数从字符串起始处搜索正则式的匹配,找不到返回None
# 贪婪匹配
print re.match( r'.*ggle', s , re.IGNORECASE ).group()  # Iggle Piggle
# 非贪婪匹配
m = re.match( r'.*?(ggle)', s , re.IGNORECASE )
print m.group()  # Iggle
print m.group( 1 )  # ggle 返回匹配中的第一个分组
 
# search函数与match类似,但是不限定匹配从字符串首部开始
print re.search( r'.akka', s , re.IGNORECASE ).group()  # Makka
 
# sub(pattern, repl, string, count, flags) 函数用于字符串替换
# pattern 匹配模式 repl替换文本或回调 string被处理字符串 count需要处理的匹配个数
# 这里使用基于序号的分组,()界定了分组范围,分组可以嵌套:
# (M(\w+))是第一个分组,(\w+)是第二个分组,(P\2)是第三个分组
# repl可以指定转移字符,\g<name>用于引用匹配的正则式分组
print re.sub( r'(M(\w+))\s+(P\2)', '\g<1> \g<3>', s )  # 去掉Makka    Pakka之间多于的空格
# 命名分组,使用(?P<GRP_NAME>)定义命名分组,使用(?P=GRP_NAME)引用命名分组
print re.sub( r'(M(?P<grp1>\w+))\s+(P(?P=grp1))', 'M\g<grp1> \g<3>', s )
# repl还可以是函数
print re.sub( r'(M(?P<grp1>\w+))\s+(P(?P=grp1))', lambda match : match.group().upper(), s )
常见问题
not all arguments converted during string formatting

原因:进行字符串格式化时,如果%后面的参数时元组,那么必须对所有元组成员进行格式化,也就是说,前面的占位符数量要和元组长度一致。

← AutoTools学习笔记
Linux内核编程知识集锦 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • 使用C语言进行文本处理
  • Go语言IO编程
  • Shinken学习笔记
  • Python单元测试
  • Python网络编程

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • Bazel学习笔记 37 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
  • Three.js学习笔记 24 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2