转载
正则表达式是一种强大的文本处理工具,它允许你根据一定的规则来搜索、匹配、替换和验证文本,适配各种编程语言。
正则表达式在计算机领域有广泛的应用,包括:
1、文本搜索和匹配:查找特定模式的字符串,如搜索包含特定关键词的文档。
2、数据验证:验证用户输入的数据是否符合特定格式,如电子邮件地址、电话号码、日期等。
3、数据提取:从文本中提取特定信息,如从HTML页面中提取链接或从日志文件中提取关键信息。
4、字符串替换:将文本中的特定模式替换为其他内容,如过滤敏感词汇。
5、日志分析:分析日志文件以提取有用的信息,如统计访问量或检测异常事件。
6、编译原理:在编译器和解释器中用于词法分析和语法分析。
7、网络爬虫:用于网页内容的抓取和处理。
常见元字符:
.:匹配任意字符,除了换行符。
例如,正则表达式 a.b 可以匹配 "axb"、"aab"、"a1b" 等。
*:匹配【前一个字符】零次或多次。
例如,正则表达式 ca*t 可以匹配 "ct"、"cat"、"caat" 等。
+:匹配【前一个字符】一次或多次。
例如,正则表达式 ca+t 可以匹配 "cat"、"caat" 等,但不匹配 "ct"。
?:匹配【前一个字符】零次或一次。
例如,正则表达式 colou?r 可以匹配 "color" 和 "colour"。
|:表示“或”操作,匹配两个或多个模式中的任何一个。
例如,正则表达式 apple|banana 可以匹配 "apple" 或 "banana"。
[]:定义字符类,匹配括号内的任何字符。
例如,正则表达式 [aeiou] 可以匹配任何元音字母。
():表示分组,用于捕获匹配的文本。
例如,正则表达式 (\d{3})-(\d{2}) 可以匹配 "123-45" 并捕获 "123" 和 "45"。
字符类用于匹配某一类字符,常见字符类:
[0-9]:匹配任何数字。
[a-z]:匹配小写字母。
[A-Z]:匹配大写字母。
[a-zA-Z]:匹配任何字母。
[^0-9]:匹配除了数字以外的字符。
[aeiou]:匹配任何元音字母。
数量词用于指定模式中字符的重复次数,常见数量词:
{n}:匹配【前一个字符】恰好 n 次。
{n,}:匹配【前一个字符】至少 n 次。
{n,m}:匹配【前一个字符】至少 n 次,但不超过 m 次。
*:匹配零次或多次。
+:匹配一次或多次。
?:匹配零次或一次。
边界匹配用于限定匹配模式的位置,常见的边界匹配符号:
^:匹配字符串的开始
$:匹配字符串的结束
\b:匹配单词的边界
\B:匹配非单词边界
正则表达式的组匹配允许你将模式中的一部分用括号括起来,以便捕获匹配的内容,这些捕获的内容可以在后续操作中使用。组匹配非常有用,特别是在需要提取或替换特定部分的文本时。
示例一:匹配日期
考虑一个匹配日期的例子,正则表达式为
(\d{4})-(\d{2})-(\d{2})
这个正则表达式会匹配形如 "2023-05-09" 的日期,并捕获年、月、日三个部分。
"2023-05-09" 匹配整个模式,捕获的结果是:年 = "2023",月 = "05",日 = "09"。
示例二:替换重复单词
正则表达式的组匹配在替换文本中的内容时非常有用。考虑一个需要将文本中的重复单词替换为一次的情况,正则表达式为
\b(\w+)\b\s+\1\b
通过这个正则表达式,可以将文本中的 "word word" 替换为 "word"。
正则表达式的反向引用是一种强大的技术,允许你在模式中引用已经捕获的文本,并在匹配时使用这些引用。这通常通过组匹配和反向引用组号来实现。反向引用在处理需要重复出现的文本模式时非常有用,例如识别重复单词、标签、括号等。
基本语法
在正则表达式中,反向引用使用组号来指示要引用的组,组号从1开始。组是通过在模式中使用圆括号 () 来创建的。一旦你捕获了一个组,你可以在后续的模式中引用它。引用的语法是 \ 后跟组号,例如 \1 表示引用组1。
示例一:匹配重复单词
假设我们有一段文本,其中有一些单词出现了两次。我们希望使用正则表达式将这些重复的单词识别出来。
文本:"Hello, hello, world, world, example, example."
正则表达式:
\b(\w+)\b.*\b\1\b
使用这个正则表达式,我们可以捕获到重复的单词 "example" 和 "world"。
示例二:HTML标签匹配
假设我们需要从HTML文档中提取所有的链接文本和链接地址。HTML标签是有嵌套关系的,我们可以使用反向引用来处理这种情况。
HTML片段:
<a href="https://www.example1.com">Example 1</a><a href="https://www.example2.com">Example 2</a><a href="https://www.example3.com">Example 3</a>
正则表达式:
<a href="([^"]+)">([^<]+)</a>
import re
str = '<a href="https://www.example1.com">Example 1</a>' \
'<a href="https://www.example2.com">Example 2</a>' \
'<a href="https://www.example3.com">Example 3</a>'
pattent = '<a href="([^"]+)">([^<]+)</a>'
data = re.findall(string=str,pattern=pattent)
print(data)
# 输出
[('https://www.example1.com', 'Example 1'), ('https://www.example2.com', 'Example 2'), ('https://www.example3.com', 'Example 3')]
对于字符串values,想要提取其中的cap所在的行信息,并输出打印出结果。
import re
values = """
[13:52:44]<fruits>
[13:52:44]apple : 11111 mv
[13:52:44]banana : 22222 mv
[13:52:44]vol : 10327 mv
[13:52:44]<batterry>
[13:52:44]vol : 10327 mv
[13:52:44]cur : 4344 ma
[13:52:44]cap : 25 %
[13:52:44]tpwr : 44.86 w
[13:52:44]<motor>
[13:52:44]bird : 999999 w
[13:52:44]monkey : 888888
[13:52:44]tpwr : 44.86 w
[13:52:44]<animals>
"""
data = re.findall("<batterry>(.*)<motor>", values, re.S) # re.S表示换行也算
print(data)
# 输出
['\n[13:52:44]vol : 10327 mv\n[13:52:44]cur : 4344 ma\n[13:52:44]cap : 25 %\n[13:52:44]tpwr : 44.86 w\n[13:52:44]']
for key in data:
volValue = re.findall("\[(.*)\]({})\s*:\s*(\d*)".format("cap"), key)
print(volValue)
# 输出
[('13:52:44', 'cap', '25')]
volDict = {}
timeList = []
valueList = []
for value in volValue:
timeList.append(value[0])
valueList.append(value[2])
volDict["time"] = timeList
volDict["vol"] = volValue[0][1]
volDict["value"] = valueList
print(volDict)
# 输出
{'time': ['13:52:44'], 'vol': 'cap', 'value': ['25']}