Python-4.字符串与正则表达式

砂糖桑
Aug 12, 2022
Last edited: 2022-8-14
type
Post
status
Published
date
Aug 12, 2022
slug
python-4
summary
本篇主要学习Python中的字符串类型以及正则表达式这个工具的使用。Python的优势是文字处理功能强大,所以字符串的操作很多,这些操作需要熟练掌握。正则表达式的应用面也非常广,它的规则和Python中使用正则表达式的方法也需要熟练掌握。
tags
Python课堂笔记合集
category
Python
icon
password
Property
Aug 14, 2022 11:17 AM
Python强大的一点就在于其文字处理。对于字符串,首先要知道的是字符串的编码,以及处理编码的一些函数;然后要知道字符串可以进行的操作与方法;对于正则表达式,首先要知道PCRE流派正则表达式的规则,然后是Python中使用正则表达式的方法。

字符串

第一篇中讲到字符串是Python中的一种基本类型,是一个字符序列,包括行内字符串和行间字符串。Python 3.x中字符串默认的编码方式是UTF-8编码。

字符编码

Unicode

Unicode是一种字符集。它于1994年正式公布,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,所以又称为统一码/万国码/单一码。不论什么字符,它都使用4字节来表达每个符号。
Python提供了ord和chr两个内置函数,用于Unicode字符与机器内部Unicode编码值之间的转换。
说明
  1. Unicode字符:我们在界面上看到的一个实际的字符。
  1. Unicode编码值:Unicode字符集将一个字符与一个唯一的编码相对应,这个编码就是对应Unicode字符的编码值。
  1. ord函数将一个字符转化为相应的Unicode编码值。
  1. chr函数将一个整数转化为相应的Unicode字符。
notion image

UTF-8编码

UTF是Unicode Transformation Format,即Unicode传送格式的缩写。它是将Unicode文件转化为字节传送流在计算机中进行存储和传输的方式,相当于Unicode的一种再编码。
Unicode字符集采用四个字节为每个字符设定了一个唯一的编码,UTF-32编码就规定在计算机中使用4字节来存储每个字符。实际上,对于前面的字符,没必要采用4字节来存储。总结一下就是UTF-32的编码方式简单直接,但是浪费了很多空间
UTF-8编码改进了UTF-32编码,采用变长编码的方式:ASCII字符只需要一个字节来编码,而一些复杂的字符则需要占用2、3、4个字节。
面试官:请讲一下 Unicode 和 UTF-8 的区别?
Unicode 和 UTF-8 的概念是一个非常基础和重要,但是却容易被忽略的问题。 在计算机系统中,所有的数据都以二进制存储,所有的运算也以二进制表示,人类语言和符号也需要转化成二进制的形式,才能存储在计算机中,于是需要有一个从人类语言到二进制编码的映射表。这个映射表就叫做字符集。 最早的字符集叫 American Standard Code for Information Interchange(美国信息交换标准代码),简称 ASCII,由 American National Standard Institute(美国国家标准协会)制定。在ASCII 字符集中,字母 A 对应的字符编码是 65,转换成二进制是 0100 0001,由于二进制表示比较长,通常使用十六进制 41 。 ASCII 字符集总共规定了 128 种字符规范,但是并没有涵盖西文字母之外的字符,当需要计算机显示存储中文的时候,就需要一种对中文进行编码的字符集,GB 2312 就是解决中文编码的字符集,由国家标准委员会发布。同时考虑到中文语境中往往也需要使用西文字母,GB 2312 也实现了对 ASCII 的向下兼容,原理是西文字母使用和 ASCII 中相同的代码,但是 GB 2312 只涵盖了 6000 多个汉字,还有很多没有包含在其中,所以又出现了 GBK 和 GB 18030,两种字符集都是在 GB 2312 的基础上进行了扩展。 可以看到,光是简体中文,就先后出现了至少三种字符集,繁体中文方面也有
面试官:请讲一下 Unicode 和 UTF-8 的区别?
由于Python默认采用UTF-8编码,所以我们甚至可以把中文作为标识符:
notion image

其他编码

我们常用的编码还有GBK编码(GB2312→GBK→GB18030),它是针对中文的一种编码方式,且向下兼容ASCII码。由于它针对中文,所以使用GBK编码存储的中文字符的大小比UTF-8编码小,所以Windows时区设为中国时系统采用GBK编码也是有道理的。
  • 编码格式是GBK时,一个中文字符占2个字符。
  • 编码格式是UTF-8时,一个中文字符占3个字符。
Python提供了encode和decode两个方法来实现编码与解码:
  1. encode:将Unicode字符转化为指定的编码方式的编码值。函数内的参数是要采用的编码。
  1. decode:将指定编码方式的编码值解码为Unicode字符。
    1. notion image
      可以到C语言中去进一步验证。gbk编码中一个汉字确实占两个字符:
      notion image

字节类型

上面的b'\xd6\xd0\xb9\xfa’就是一个字节类型(bytes)的常量。在’’前面加b表示这是一个字节类型,’’里面的每一个字符是\x00-\xff之间的一个十六进制数或一个ASCII字符。
notion image
它的操作和字符串很相似,了解即可。

索引与分片

索引

索引包括正索引与负索引。正索引的编号范围是0~len(str)-1,负索引的编号范围是-len(str)~-1。所以可以很方便地访问到字符串后面的字符。
notion image

分片

字符串的分片操作可以从给定的字符串中分离出部分字符。它的格式为str[start: end: step]
  1. 区间的范围为左闭右开,即不包括end对应的字符。
  1. step缺省默认为1。str[start:]表示从下标为start的位置一直到字符串末尾;str[:end]表示从字符串开始一直到end-1的位置。
  1. start和end可以是正索引,也可以是负索引,还可以混用。但要求start经一个或多个step能得到end,否则分片返回的字符串为空。
  1. 如果要实现逆序输出到字符串开头,使用正索引是无法实现的,需要使用负索引:str[start:-(len(str)+1):-1]。而使用正索引无法切到第一个字符。(实际上要使用正索引可以缺省结束的位置,如str[start::-1]就可以从start逆序输出到字符串开头)
    1. notion image
  1. 提供的start和end可以超过字符串的范围,超过了就认为一直切到底。

字符串的操作

使用运算符可以对字符串进行操作,从C++的角度可以认为对这些运算符进行了重载。

算数运算符

需要注意这些运算都不会改变字符串本身,而是返回一个新的字符串。
  1. 使用+连接字符串: 'abc'+'def'='abcdef'
  1. 使用*重复字符串: 'abc'*2='abcabc'

关系运算符

  1. 使用=判断两个字符串是否是相同
  1. 使用>、<、>=、<=来比较两个字符串的大小。
    1. 字符的大小比的是字符编码值的大小,如英文字母比的是ASCII码的大小。字符串比大小就是从左到右比较个字符的大小,直到比较出结果。需要记住常用字符的ASCII码:0-9:48-57;A-Z:65-90;a-z:97-122
  1. 使用in或not in判断前者是否是后者的字串(区别子串与子序列)。

字符串的常用方法

函数与方法的区别
称类/对象的成员函数为方法。具体来说,len(str)这种形式的称为函数;str.upper()这种形式的称为方法。
  1. 大小写转换
      • str.upper(): 全部字母转换为大写。
      • str.lower(): 全部字母转化为小写。
      • str.swapcase(): 大小写互换。
      • str.title(): 每个单词的首字母大写。
      • str.capitalize(): 字符串的首字母大写。
  1. 字符串对齐
      • str.ljust(width,fillchar):输出width个字符,原来的字符串左对齐,右边用fillchar填充。
      • str.rjust(width,fillchar):输出width个字符,原来的字符串右对齐,左边用fillchar填充。
      • str.center(width,fillchar):输出width个字符,原来的字符串在新串的中间,两边用fillchar填充。
  1. 字符串搜索
      • str.find(substr): 返回str从左到右第一个出现substr的首字符的位置;没有则返回-1。
      • str.rfind(substr): 返回str从右到左第一个出现substr的首字符的位置;没有则返回-1。
      • str.count(substr): 计算substr在str中出现的次数。
  1. 字符串替换
      • str.replace(oldstr,newstr,max): 将oldstr替换为newstr,max表示最多替换的次数,可省略。
  1. 字符串的拆分与组合
      • str.strip(seq,max): 以seq作为分隔符,将str从左到右拆分为一个序列,max表示最多拆分的次数,可省略。
      • str.rstrip(seq,max): 从右到左拆分str为一个序列。
      如果seq不是str的子串,那么序列中的元素就是这个字符串本身。seq缺省表示以空格作为分隔。
      • str.join(seq): 以str作为序列seq中元素的分隔,将序列合并成一个字符串。
        • notion image

正则表达式

正则表达式Regular Expression是一种文本模式,它是一些元字符和普通字符的组合,用于实现对字符串的过滤逻辑,常常用来检索或替换符合某种模式的文本

元字符

元字符meta character是具有特定含义的字符,它使得正则表达式具有匹配能力。
Python正则表达式中的元字符 (1)
Title
描述
零次或更多次匹配前面的字符。例如,zo* 匹配 z 或 zoo
一次或更多次匹配前面的字符。例如,zo+ 匹配 zoo,但是不匹配 z
零次或一次匹配前面的字符。例如,a?ve? 匹配 never 中的 ve
匹配任何单个字符,但换行符除外。
匹配输入的开始部分。
匹配输入的结束部分。
将特殊字符标记为字面值,或将普通字符标记为特殊值
将()中的内容当作一个整体看待。
匹配 x 或 y。 例如,z|wood 匹配 z 或 wood。(z|w)oo 匹配 zoo 或 wood
n 是一个非负整数。精确匹配 n 次。例如,o{2} 不匹配 Bob 中的 o,但是匹配 foooood 中的前两个 o
m 和 n 变量是非负整数。至少 n 次且至多 m 次匹配前面的字符。例如,o{1,3} 匹配 fooooood 中的前三个 o;m或n可以省略,表示至少或至多匹配那么多次
一个字符集。匹配任意一个包含的字符。例如,[abc] 匹配 plain 中的 a
一个否定字符集。匹配任何未包含的字符。
字符范围。匹配指定范围中的任何字符。例如,[a-z] 匹配英语字母中的任何小写的字母字符。
一个否定字符范围。匹配未在指定范围中的任何字符。例如,[m-z] 匹配未在范围 m 到 z 之间的任何字符。
匹配数字字符。
匹配任何数字、字符和下划线。
匹配任何空白字符,包括空白、制表符、换页字符等等。
  1. 首先需要区别括号的含义:()将内部的字符串作为一个整体;{}表示匹配次数;[]表示匹配其中的一个字符,可以用-表示一个范围。
  1. 然后要知道贪婪匹配与懒惰匹配。贪婪匹配会尽可能多地匹配字符,而懒惰匹配则是尽可能少地匹配。

Python使用正则表达式

Python中使用正则表达式有两种方式:使用正则表达式对象和使用正则表达式字符串。两种方式的区别是使用正则表达式对象调用的是它的方法,而使用字符串调用的是函数。使用正则表达式的基本步骤如下:
  1. 引入re模块
  1. 编辑正则表达式字符串,注意正则表达式必须是正确的写法,不然后面会报错。
  1. 如果要使用正则表达式对象,使用re.compile()将正则表达式字符串编译为正则表达式对象。使用正则表达式对象可以加快处理速度。
  1. 正则字符串调用函数或正则对象调用方法。
需要掌握可以调用的函数或方法。

match

match的作用是从字符串的最左边开始匹配不能从中间开始匹配,相当于自带了$。
import re text='one1 two2 three3 four4' pattern='.*?\d+' # 使用正则字符串匹配到one1 print(re.match(pattern,text).group()) # 使用正则对象匹配到one1 regObj=re.compile(pattern) print(regObj.match(text).group())

search

search的作用是扫描整个字符串,返回从左到右第一个匹配的结果。它可以从中间开始匹配
import re text='one1 two2 three3 four4' pattern="\s(\w)*" # 使用正则字符串匹配到 two2 print(re.search(pattern,text).group()) # 使用正则对象匹配到 two2 regObj=re.compile(pattern) print(regObj.search(text).group())

findall

findall的作用是扫描整个字符串,以列表的形式返回全部能匹配的结果。
import re text='one1 two2 three3 four4' pattern="\d" # 使用正则字符串匹配到数字,返回列表 print(re.findall(pattern,text)) # 使用正则对象匹配到数字,返回列表 regObj=re.compile(pattern) print(regObj.findall(text))

finditer

和findall类似,区别是将结果组成一个迭代器返回。但是从迭代器取到的是一个match对象,所以还需要调用group()方法
import re text='one1 two2 three3 four4' pattern="\d" # 使用正则字符串匹配到数字,返回列表 results=re.finditer(pattern,text) for result in results:print(result.group()) # 使用正则对象匹配到数字,返回列表 regObj=re.compile(pattern) results=regObj.finditer(text) for result in results:print(result.group())
正则表达式深入研究是很高深的,什么有限自动机听着就很高深——本篇这点仅做入门用。re模块的常量还没有仔细看,之后可以再看看下面这篇文章。
Python正则表达式,这一篇就够了!
之前我们讲解了 正则表达式语法 的起源、发展、流派、语法、引擎、优化等相关知识,今天我们主要来学习一下 正则表达式在 Python语言 中的应用 ! 大多数编程语言的正则表达式设计都师从Perl,所以语法基本相似,不同的是每种语言都有自己的函数去支持正则,今天我们就来学习 Python中关于 正则表达式的函数。 re模块主要定义了9个常量、12个函数、1个异常,每个常量和函数猪哥都会通过实际代码案例讲解,让大家能更直观的了解其作用! 注:为避免出现代码格式错乱,猪哥尽量使用代码截图演示哦。 一、re模块简介 聊到Python正则表达式的支持,首先肯定会想到 re库,这是一个Python处理文本的 标准库 。 标准库的意思表示这是一个 Python内置模块,不需要额外下载,目前Python内置模块大概有300个。可以在这里查看Python所有的内置模块: https:// docs.python.org/3/py-mo dindex.html#cap-r 因为re是内置模块,所以不需要再下载,使用时直接引入即可: import re re模块官方文档: https:// docs.python.org/zh-cn/3 .8/library/re.html re模块库源码: https:// github.com/python/cpyth on/blob/3.8/Lib/re.py 二、re模块常量 常量即表示不可更改的变量,一般用于做标记。 re模块中有9个常量,常量的值都是int类型! 上图我们可以看到,所有的常量都是在 RegexFlag枚举类来实现,这是在Python 3.6做的改版。在Python 3.6以前版本是直接将常量写在re.py中,使用枚举的好处就是方便管理和使用! 下面我们来快速学习这些常量的作用及如何使用他们,按常用度排序! 1. IGNORECASE 语法: re.IGNORECASE 或简写为 re.I 作用: 进行忽略大小写匹配。 2.
Python正则表达式,这一篇就够了!
Python-3.程序结构Python-5.列表与元组