通用正则表达式 持续更新~

本文详细介绍了Python中正则表达式的使用,包括判断数字字符、电话号码的查找以及字符组、元字符、转义和排除型字符组的概念和应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引例

判断数字字符

def isDigit(ch):
return re.search(ch, "[0-9]") != None
  • 这里真正要关心的就是正则表达式[0-9],它表示“从0到 9之间的任意字符"

    re.search()是正则表达式运算函数,它判断ch能否由正则表达 式[0~9]匹配,可以则返回一个结果,否则返回None

判断字符串str是否电话号码

return re.search(str, "[1-9][0-9](6,7}") != None
  • 这个正则表达式最开始是[1-9],表示第一个字符必须是1〜9之间的数字字符;之后是 [0-9] {6,7},表示长度在6和7之间,由0〜9之间的数字字符组成的字符串(两部分加起来, 整个字符串的长度在7和8之间)。

找出一段文本中所有的固定电话号码

return re.findall(str, '(?<![0~9])[1-9][0-9]{6,7}(?![0-9])')
  • 这个正则表达式之前多出了(?<! [0-9〕),表示“之前不能是[0-9]之后多出了 (?! [0-9]),表示“之后不能是[0-9]虽然稍微复杂点,但意思明确,而且不难理解

正文

普通字符组

字符组(CharacterClass) 是正则表达式最基本的结构之一,要理解正则表达式的’‘灵活”, 认识它是第一步。

顾名思义,字符组就是一组字符,在正则表达式中,它表示“在同一个位置可能出现的各种 字符”,其写法是在一对方括号[和]之间列出所有可能出现的字符,简单的字符组比如[ab]、 [314]、[#・?]在解决一些常见问题时,使用字符组可以大大简化操作,下面举“匹配数字字符” 的例子来说明。

字符可以分为很多类,比如数字、字母、标点等。有时候要求“只出现一个数字字符”,换 句话说,这个位置上的字符只能是0、1、2、…、8、9这10个字符之一。要进行这种判断,通 常的思路是:用10个条件分别判断字符是否等于这10个字符,对10个结果取“或”,只要其中 一个条件成立,就返回True,表示这是一个数字字符

介绍完关于Python的基础知识,继续讲解字符组。字符组中的字符排列顺序并不影响字符 组的功能,出现重复字符也不会影响,所以[0123456789]完全等价于[9876543210]、 [1029384756]、 [9988876543210]。

不过,代码总是要容易编写,方便阅读,正则表达式也是一样,所以一般并不推荐在字符组 中出现重复字符。而且,还应该让字符组中的字符排列更符合认知习惯,比如[0123456789] 就好过[0192837465]。为此,正则表达式提供了-范围表示法(range),它更直观,能进一步 简化字符组。

所谓“范围表示法”,就是用也丑的形式表示X到y整个范围内的字符,省去一一列出的麻烦,这样[0123456789]就可以表示为[0-9]。如果你觉得这不算什么,那么确实比 [abcdefghi j klmnopqrstuvwxyz ]简单太多了。

你可能会问,“范围表示法’'的范围是如何确定的?为什么要写作[0-9],而不写作[9-0]?

要回答这个问题,必须了解范围表示法的实质。在字符组中,二表示的范围,一般是根据字 符对应的码值(Code Point,也就是字符在对应编码表中的编码的数值)来确定的,码值小的字 符在前,码值大的字符在后。在ASCII编码中(包括各种兼容ASCII的编码中),字符0的码值 是48 (十进制),字符9的码值是57 (十进制),所以[0-9]等价于[0123456789];而[9-0] 则是错误的范围,因为9的码值大于0,所以会报错。

正则表达式判断数字字符

re.search("[0123456789“], charStr) != None

re.search()是Python提供的正则表达式操作函数,表示“进行正则表达式匹配”;charStr 仍然是需要判断的字符串,而[0123456789]则是以字符串形式给出的正则表达式,它是一个字 符组,表示“这里可以是0、1、2、…、8、9中的任意一个字符。只要charStr与其中任何一个 字符相同(或者说“charStr可以由[0123456789]匹配"),就会得到一个Matchobject对象;否则,返回None所以判断结果是否为None, 就可以判断charStr是否是数字字符。

正则表达式判断数字字符在各种语言中的应用

NET (C#)

〃能匹配则返回true,否则返回false

Regex.IsMatch(charStr, "[0123456789]H;

Java

〃能匹配则返回true,否则返回false

charStr.matches("[0123456789]");

JavaScript

〃能匹配则返回true,否则返回false

[0123456789]/.test(charStr);

PHP

〃能匹配则返回1,否则返回。

preg_match('/[0123456789]/", charStr);

Python

#能匹配则返回RegexObject,否则返回None

re.search("[0123456789]", charStr)

Ruby

#能匹配则返回。,否则返回nil

charStr =~ /[0123456789]/

[0-9a-fA-F]准确判断十六进制字符

re.search("^[0-9a-fA-F]$","0")	!=	None	#	=>	True

re.search("^[0-9a-fA-F]$","c")	!=	None	#	=>	True

re.search("^[0-9a-fA-F]$","i")	!=	None	#	=>	False

re.search("^[0-9a-fA-F]$","C")	!=	None	#	=>	True

re.search("^[0-9a-fA-F]$","J")	!=	None	#	=>	False

在不少语言中,还可以用转义序列\xAex来表示一个字符,其中\x是固定前缀,表示转义序 列的开头,是字符对应的码值(Code Point,详见第127页,下文用行127表示),是一个两 位的十六进制数值。比如字符A的码值是41 (十进制则为65),所以也可以用\x41表示。

字符组中有时会出现这种表示法,它可以表现一些难以输入或者难以显示的字符,比如\x7F; 也可以用来方便地表示某个范围,比如所有ASCII字符对应的字符组就是【\x00-\x7F],代码

[\x00-\x7F]\准确判断ASCII字符

re.search("^[\x00-\x7F]$","c")!=None # =>True

re.search("^[\xe0-\x7F]$","I")!=None # =>True

re.search("^[\x00-\x7F]$","e")!=None # =>True

re.search("^[\x00-\x7F]$","<")!=None # =>True

元字符与转义

在上面的例子里,字符组中的横线二并不能匹配横线字符,而是用来表示范围,这类字符叫 做元字符(meta-character)字符组的开方括号[、闭方括号]和之前出现的:、§都算元字符。在 匹配中,它们有着特殊的意义。但是,有时候并不需要表示这些特殊意义,只需要表示普通字符 (比如“我就想表示横线字符•”),此时就必须做特殊处理。

先来看字符组中的-,如果它紧邻着字符组中的开方括号[,那么它就是普通字符,其他情况 下都是元字符;而对于其他元字符,取消特殊含义的做法都是转义,也就是在正则表达式中的元 字符之前加上反斜线字符

如果要在字符组内部使用横线二,最好的办法是将它排列在字符组的最开头。[-09]就是包 含三个字符*-*、0、*9的字符组:[0-9]是包含。0〜9这10个字符的字符组,[-0-9]则是由“-”范 围表示法”0-9和横线二共同组成的字符组,它可以匹配11个字符

位置不同含义不同

- 位置产生的含义

#作为普通字符
re.search("[-09]$","3")!=None	#=>False
re.search("[-09]$","-")!=None	#=>True
#作为元字符
re.search("[-9]$","3")!=None	#=>True
re.search("[0-9]$","-")!=None	#=>False
#转义之后作为普通字符
re.search("[\-9]$","3")!=None	#=>False
re.search("[\-9]$","-")!=None	#=>True

仔细观察会发现,在正文里说“在正则表达式中的元字符之前加上反斜线字符\”,而在代码 里写的却不是[0-9],而是[0\-9]这并不是输入错误。

因为在这段程序里,正则表达式是以字符串(String)的方式I提供的,而字符串本身也有关 于转义的规定(你或许记得,在字符串中有\n> \t之类的转义序列)。上面说的“正则表达式”, 其实是经过“字符串转义处理”之后的字符串的值,正则表达式[0-9]包含6个字符:[、0、\、 -、9、],在字符串中表达这6个字符;但是在源代码里,必须使用7个字符: \需要转义成\, 因为处理字符串时,反斜线和之后的字符会被认为是转义序列(Escape Sequence),比如\n> \t 都是合法的转义序列,然而\-不是。

这个问题确实有点麻烦。正则表达式是用来处理字符串的,但它又不完全等于字符串,正则 表达式中的每个反斜线字符、在字符串中(也就是正则表达式之外)还必须转义为\。所以之 前所说的是“正则表达式[0\-9]”,程序里写的却是[0\\-9],这确实有点麻烦。

不过,Python提供了原生字符串(Raw String),它非常适合于正则表达式:正则表达式是怎 样,原生字符串就是怎样,完全不需要考虑正则表达式之外的转义(只有双引号字符是例外,原生字符串内的双引号字符必须转义写成\")。原生字符串的形式是 r”string”也就是在普通字符串之前添加r

]位置产生的含义

#未转义的]
re.search(r"[012]345]$","2345")!=None	#=>True
re.search(r"[12]345]$","5")!=None	#=>False
re.search(r"[012]345]$","]")!=None	#=>False
#转义的]
re.search(r"^[812\]345]$","2345")!=None	#=>False
re.search(r"[912\]345]$","5")!=None	#=>True
re.search(r"[012\]345]$","]")!None	#=>True

除去字符组内部的-,其他元字符的转义都必须在字符之前添加反斜线,[的转义也是如此。 如果只希望匹配字符串[012],直接使用正则表达式[012]是不行的,因为这会被识别为一个字 符组,它只能匹配0、1、2这三个字符中的任意一个;而必须转义,把正则表达式写作[012], 请注意,只有开方括号[需要转义,闭方括号]不需要转义

取消其他元字符的特殊含义

re.search(r"[012]345]$","3")!=None	#=False
re.search(r"[012\\]345]$","3")!=None	#=>True
re.search(r"[012]$","[012]")!None	#=>False
re.search(r"\[012]$","[012]")!=None#=>True

原生字符串的使用

#原生字符串和字符串的等价
r"^[0\-9]$"="^[0\\-9]$"		#=True
#原生字符串的转义要简单许多
re.search(r"[\-9]$","3")!=None	#=>False
re.search(r"[\-9]$","-")!None	#=True

排除型字符数组

在方括号B中列出希望匹配的所有字符,这种字符组叫做“普通字符组”,它的确非常方 便。不过,也有些问题是普通字符组不能解决的。

给定一个由两个字符构成的字符串str,要判断这两个字符是否都是数字字符,可以用 [0-9] [0-9]来匹配。但是,如果要求判断的是这样的字符串——第一个字符不是数字字符,第 二个字符才是数字字符(比如A8、x6) ——应当如何办?数字字符的匹配很好处理,用[0-9]排除型字符组(Negated Character Class)非常类似普通字符组B,只是在开方[之后紧跟一个脱字符^,写作[^……]就表示0-9之外的字符,表示“在当前位置,匹配一个没有列岀的字符”。所以[^0-9]“。0〜9之外的字符”,也就是“非数字字符”。那么,L0-9] [0-9]就可以解决问题了

排除型字符组必须匹配一个字符

除了开方括号[之后的^排除型字符组的用法与普通字符组几乎完全相同,唯一需要改动的 是:在排除型字符组中,如果需要表示横线字符-(而不是用于“-范围表示法”),那么-应该紧跟 在^之后;而在普通字符组中,作为普通字符的横线-应该紧跟在开方括号之后

re.search(r"A[A0-9][0-9]$", "8") != None	# => True
re.search(r"A[A0-9][0-9]$", ”A8“)!= None	# => True

ASCII对照表

ASCII值控制字符ASCII值控制字符ASCII值控制字符ASCII值控制字符
0NUL32(space)64@96
1SOH3365A97a
2STX3466B98b
3ETX35#67C99c
4EOT36$68D100d
5ENQ37%69E101e
6ACK38&70F102f
7BEL3971G103g
8BS40(72H104h
9HT41)73I105i
10LF42*74J106j
11VT43+75K107k
12FF44,76L108l
13CR45-77M109m
14SO46.78N110n
15SI47/79O111o
16DLE48080P112p
17DCI49181Q113q
18DC250282R114r
19DC351383X115s
20DC452484T116t
21NAK53585U117u
22SYN54686V118v
23TB55787W119w
24CAN56888X120x
25EM57989Y121y
26SUB58:90Z122z
27ESC59;91[123{
28FS60<92\124|
29GS61=93]125}
30RS62>94^126~
31US63?95127DEL
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值