中文正则表达式匹配

正则表达式

单字符匹配

字符功能
.匹配任意一个字符(除了\r和\n)
[ ]匹配[ ]中列举的字符
\d匹配数字(0-9)
\D匹配非数字
\s匹配空白,即空格、tab键、换行符、\r
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、_、中文字符
\W匹配非单词字符
[^x]匹配除了x以外的任意字符

其中,
\d 等同于[0-9],
\D等同于[^0-9],
\w 等同于[a-zA-Z0-9_],
\W等同于[^a-zA-Z0-9_]。

数量表示

字符功能
*匹配前一个字符0次或无限次
+匹配前一个字符1次或无限次
匹配前一个字符0次或1次,即要么有要么没有
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符至少出现m次,至多出现n次

其中,
*等同于{0,},
+等同于{1,},
?等同于{0,1}

边界表示

字符功能
^匹配字符串开头
$匹配字符串结尾
\b匹配单词的边界
\B匹配非单词边界

匹配分组

字符功能
|匹配左右任意一个表达式
(ab)把括号中字符作为一个分组
\num引用分组num匹配到的字符串
(?P<name>)给分组起别名
(?P=name)引用别名为name分组匹配到的字符串

正则表达式测试

了解了正则表达式的匹配规则,怎么测试编写的正则表达式是否正确呢?一般来说,有三种方式:
(1)下载测试工具测试
这里推荐RegexBuddy。RegexBuddy是一款正则表达式测试工具,支持多种编程语言的正则式测试,匹配结果在原文本中高亮。根据编写的正则式,RegexBuddy还提供相应语言的代码自动生成功能。不过网上下到的破解版该功能可能缺失。
除此之外RegExBuilder也是一款正则表达式测试工具。

(2)编写代码测试
也可以用编程语言,调用相应的函数库编写正则表达式测试。比如python的re模块等等。

(3)使用在线正则表达式网站测试
http://tool.chinaz.com/regex

RegexBuddy工具

打开工具是这样的:
在这里插入图片描述
Match模块下,可以选择多种语言(此处选了python)。
在这里插入图片描述

单字符匹配
示例1:使用 “.” 进行任意字符匹配
在这里插入图片描述
Test下输入要匹配的文本内容。Highlight选中表示在原文中高亮匹配结果(黄蓝均是匹配结果,交错显示),List All 表示在下方列出所有匹配结果。
“.” 匹配任意一个字符(除了\r和\n)

示例2:使用“ [ ]” 匹配[ ]中列举的字符
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

示例3:使用“ \d” 匹配数字0-9
在这里插入图片描述

示例4:使用“ \D” 匹配非数字
在这里插入图片描述
可以看到,第一行与第二行之间的换行符也被当成非数字匹配,出现了多个空结果(4个空行)。
在这里插入图片描述
选择第二个List All模式查看匹配结果,发现四个空行变成了两行。一行为“\r”符,一行为“\n”符。(\n为换行,相当于按了向下的方向键;\r为回车,相当于光标移至当前行行首)
两种不同查看模式下的行数差异可能是RegexBuddy工具自身格式的原因,这里我们知道“\D”模式下,回车换行符\r、\n都会当成非数字被匹配就可以了。
除此之外,\t(一个tab键)也会当成非数字被匹配。

示例5:使用“ \s” 匹配空白
在这里插入图片描述
空白包括空格、\t(一个tab键)、\n、\r。

示例6:使用“ \S” 匹配非空白
在这里插入图片描述

示例7:使用“ \w” 匹配单词字符
在这里插入图片描述
单词字符包括a-z、A-Z、0-9、下划线_、中文字符。

示例8:使用“ \W” 匹配非单词字符
在这里插入图片描述
非单词字符即单词字符以外的所有字符,包括空格、\t、\n、\r。

数量表示
示例1:使用“ *” 匹配前一个字符0次或无限次
在这里插入图片描述
这里“ w* ”匹配w出现0次或无限次。虽然待匹配文本“we”中只有一个w,但是匹配结果有两个:一个w,一个为空。
这是因为空结果匹配了w出现了0次的情况,我们可以把每个字符看成是自身和空字符的拼接,使用“ x* ”对字符匹配,若x与字符相同,则返回其本身;若不同,返回一个匹配的空结果。(这里与python里使用re匹配的结果稍有不同,re是即使x与字符相同,对其本身也要进行空字符匹配,即会返回两个结果)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
python的re模块,对文本“e”匹配正则表达式“e*”:

>>> import re
>>> s = re.findall('e*', 'e')
>>> print(s)
['e', '']

可以看到,RegexBuddy对匹配到的字符不再进行空字符匹配,对未匹配到的字符才进行空字符匹配。python的re模块对匹配到的字符和未匹配的字符都会进行空字符匹配。

示例2:使用“ +” 匹配前一个字符1次或无限次
在这里插入图片描述

示例3:使用“ ?” 匹配前一个字符0次或1次,即要么有要么没有
在这里插入图片描述
涉及到可以0次,所以和“ * ”的匹配非常相似。只是“ * ”可以匹配无限次,“ ?” 最多一次。所以连续出现的字符会被拆开匹配。

示例4:使用“ {m}” 匹配前一个字符出现m次
在这里插入图片描述
在这里插入图片描述
示例5:使用“ {m,}” 匹配前一个字符至少出现m次
在这里插入图片描述
示例6:使用“ {m,n}” 匹配前一个字符至少出现m次,至多出现n次
在这里插入图片描述
在这里插入图片描述
边界表示
示例1: 使用“^” 匹配字符串开头
在这里插入图片描述

示例2:使用 “$” 匹配字符串结尾
在这里插入图片描述
在这里插入图片描述

复合使用“^”和“$”,匹配以“一”开头,以“三”结尾的句子
在这里插入图片描述
示例3:使用 “\b” 匹配单词的边界
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
“\b”匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”(来自维基百科)。
网上有这样一种说法, \b匹配这样的位置:它的前一个字符和后一个字符不是或不存在\w(单词字符,即a-z、A-Z、0-9、_、中文字符)。

示例4:使用 “\B” 匹配非单词边界
在这里插入图片描述
在这里插入图片描述
“\B”匹配非单词边界。例如,“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

匹配分组
示例1:使用 “| ” 匹配左右任意一个表达式
在这里插入图片描述

示例2:使用 “(ab)” 把括号中的字符作为一个分组
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
python中的“*”默认贪婪匹配,即有多种字符串序列符合匹配模式时,默认选择最长的序列作为匹配结果。若希望选择最短的序列,需要使用“*?”,开启非贪婪模式。
在这里插入图片描述
使用“()”匹配出的结果会作为一个分组,正则表达式中有几个括号对,就会对应几个分组。这里,gropu2对应第二次出现括号对标签所对应的分组,显示匹配结果,则只将第二个分组中匹配的结果展示出来。

示例3:使用 “(?P<name>)” 给分组起别名
在这里插入图片描述
在这里插入图片描述

Python re模块

可参考:
https://www.runoob.com/python/python-reg-expressions.html

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import re


text_str = '南充高坪机场(Nanchong Gaoping Airport ICAO:ZUNC;IATA:NAO)位于南充市主城区正东方向,距离南充市中心直线' \
           '距离7.5公里,交通便利,飞行区等级属于4C级预留4D机场。机场属浅丘地形,机场标高365米,全年平均雾日61.7天,净空条件良' \
           '。目前已经成为川渝地区航空客货集散枢纽之一。'

pattern = re.compile(r'\w+')
result = pattern.match(text_str)
print('match结果:{}'.format(result.group()))

result = pattern.search(text_str)
print('search结果:{}'.format(result.group()))

result = pattern.findall(text_str)
print('findall结果:{}'.format(result))

注意,match 和 search 是匹配一次,findall 匹配所有。
输出:
在这里插入图片描述

提取文本的省市区地理位置信息

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import re

s = '南充高坪机场(Nanchong Gaoping Airport ICAO:ZUNC;IATA:NAO)位于南充市主城区正东方向,距离南充市中心直线' \
           '距离7.5公里,交通便利,飞行区等级属于4C级预留4D机场。机场属浅丘地形,机场标高365米,全年平均雾日61.7天,净空条件良' \
           '。目前已经成为川渝地区航空客货集散枢纽之一。'
print(' {}'.format(s))

pattern = r'([0-9\d\a-z\d\u4e00-\u9fa5]{2,15}?(?:省|自治区)){0,1}' \
          r'([0-9\d\a-z\d\u4e00-\u9fa5]{2,15}?(?:自治州)){0,1}' \
          r'([0-9\d\a-z\d\u4e00-\u9fa5]{2,20}?(?:市)){0,1}' \
          r'([0-9\d\a-z\d\u4e00-\u9fa5]{2,20}?(?:区|县|旗)){0,1}' \
          r'([0-9\d\a-z\d\u4e00-\u9fa5]{2,10}?(?:州)){0,1}'

location = re.findall(r"位于(.+?)[,|。]", s)
print('location:{}'.format(location))
result = re.search(pattern, location[0])
print(result.groups())

针对pattern的多个正则表达式挨个匹配,结果:
在这里插入图片描述

题外话,python的translate() 方法,可以根据参数table给出的表转换字符。
参考:https://www.runoob.com/python3/python3-string-translate.html

import string

s = '南充高坪机场(Nanchong Gaoping Airport ICAO:ZUNC;IATA:NAO)位于南充市主城区正东方向,距离南充市中心直线' \
           '距离7.5公里,交通便利,飞行区等级属于4C级预留4D机场。机场属浅丘地形,机场标高365米,全年平均雾日61.7天,净空条件良' \
           '。目前已经成为川渝地区航空客货集散枢纽之一。'
print(' {}'.format(s))

# 将原句子中的字母大写转小写
s = s.translate(str.maketrans(string.ascii_lowercase, string.ascii_uppercase, string.punctuation))
print('1.{}'.format(s))

# 抛弃句子中的一些标点符号
s = s.translate(str.maketrans('', '', string.punctuation))
print('2.{}'.format(s))

# 抛弃句子中的数字
s = s.translate(str.maketrans('', '', string.digits))
print('3.{}'.format(s))

# 抛弃句子中的字母
s = s.translate(str.maketrans('', '', string.ascii_uppercase+string.ascii_lowercase))
print('4.{}'.format(s))

# 抛弃句子中的指定字符
s = s.translate(str.maketrans('', '', ';[]:()'))
print('5.{}'.format(s))

输出:
在这里插入图片描述
Python 2.0中抛弃标点符号和数字:

text = text.translate(None, string.punctuation)
text = text.translate(None, '1234567890')

Python 3.0等价物:

text = text.translate(str.maketrans('','',string.punctuation))
text = text.translate(str.maketrans('','','1234567890'))

maketrans前两个参数表示“不做任何事情”,第三个参数表示将任何标点或数字转换为None(即删除它们)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值