Python 爬虫入门(十二):正则表达式「详细介绍」

Python 爬虫入门(十二):正则表达式

  • 前言
  • 一、正则表达式的用途
  • 二、正则表达式的基本组成元素
    • 2.1 特殊字符
    • 2.2 量词
    • 2.3 位置锚点
    • 2.4 断言
    • 2.5 字符集
    • 2.6 字符类
      • 2.6.1 基本字符类
      • 2.6.2 常见字符类简写
      • 2.6.3 POSIX字符类
      • 2.6.4 组合使用
  • 三、 正则表达式语法规则
  • 四、高级特性
    • 4.1 回溯引用(捕获组)
      • 示例:匹配重复的单词
    • 4.2 非捕获组
      • 示例:非捕获组的使用
    • 4.3 贪婪与非贪婪匹配
      • 示例:贪婪与非贪婪的区别
    • 4.4 零宽断言
      • 示例:使用零宽断言匹配特定模式
  • 五、 实战案例
    • 5.1 网页数据抓取
      • 代码示例:提取图片地址
    • 5.2 数据清洗
      • 代码示例:清理电话号码中的特殊字符
    • 5.3 提取超链接
      • 代码示例:提取所有的URL
    • 5.4 提取网页中的文本内容
      • 代码示例:提取段落文本
    • 5.5 从JSON数据中提取特定键值对
      • 代码示例:提取JSON中的特定值
    • 5.6 清理HTML标签
      • 代码示例:去除HTML标签
  • 六、 总结

前言

  • 正则表达式(Regular Expression),在编程语言中通常缩写为regex或regexp,是一种用于字符串搜索和操作的模式描述方法。它通过定义一系列的规则来匹配、查找和管理文本数据。

正则表达式在线校验: https://tool.oschina.net/regex/
在这里插入图片描述

一、正则表达式的用途

正则表达式在各种编程任务中都有广泛的应用。以下是一些常见的用途:

  1. 网页数据抓取:通过解析HTML、JSON等格式化数据,爬虫可以精确定位并提取目标数据,例如从网页中提取标题、链接、图片地址等;
  2. 数据验证:用于验证用户输入是否符合特定格式,如邮箱地址、电话号码、邮政编码等;
  3. 文本搜索和替换:能够高效地在文本中查找和替换特定的字符串或模式;
  4. 字符串操作:用于复杂的字符串操作,如拆分、拼接、重构字符串等。

二、正则表达式的基本组成元素

在介绍正则表达式之前,我们需要了解一些基本的组成元素:

2.1 特殊字符

  • 任意字符. 匹配除换行符之外的任意单个字符。
  • 任意数字\d 等同于 [0-9],匹配任意一个数字字符。
  • 任意非数字\D 等同于 [^0-9],匹配任意一个非数字字符。
  • 任意字母[a-z] 匹配任意一个英文小写字母。
  • 任意非字母[^a-z] 匹配任意一个非英文小写字母的字符。

2.2 量词

  • *:出现0次或多次。
  • +:出现1次或多次。
  • ?:出现0次或1次。
  • {n}:确定出现n次。
  • {n,}:至少出现n次。
  • {n,m}:出现n到m次。

2.3 位置锚点

  • ^:行的开头。
  • $:行的结尾。

2.4 断言

  • \b:单词边界。
  • \B:非单词边界。

2.5 字符集

  • []:定义一个字符集,匹配其中的任意单个字符。
  • [^]:取反,匹配不在字符集中的任意单个字符。

2.6 字符类

字符类用于定义一组可以匹配的字符。它们通过方括号[]来表示,在匹配过程中,只要目标字符属于字符类中定义的范围,就会成功匹配。

2.6.1 基本字符类

  • [abc]:匹配abc中的任意一个字符。例如,正则表达式[abc]可以匹配字符串cat中的c

  • [^abc]:匹配除abc之外的任意字符。例如,正则表达式[^abc]可以匹配字符串dog中的d

  • [a-z]:匹配所有小写字母(从az)。例如,正则表达式[a-z]可以匹配字符串hello中的h

  • [A-Z]:匹配所有大写字母(从AZ)。例如,正则表达式[A-Z]可以匹配字符串Hello中的H

  • [0-9]:匹配所有数字字符(从09)。例如,正则表达式[0-9]可以匹配字符串year2024中的2

  • [a-zA-Z0-9]:匹配所有字母和数字,即大小写字母和数字组合。例如,正则表达式[a-zA-Z0-9]可以匹配字符串Pass123中的Pas等字符。

2.6.2 常见字符类简写

在正则表达式中,为了方便书写和理解,常用字符类通常会有一些简写形式:

  • \d:匹配任意一个数字字符,等同于[0-9]

  • \D:匹配任意一个非数字字符,等同于[^0-9]

  • \w:匹配任意一个字母、数字或下划线字符,等同于[a-zA-Z0-9_]

  • \W:匹配任意一个非字母、非数字和非下划线字符,等同于[^a-zA-Z0-9_]

  • \s:匹配任意一个空白字符,包括空格、制表符、换行符等,等同于[ \t\n\r\f\v]

  • \S:匹配任意一个非空白字符,等同于[^ \t\n\r\f\v]

2.6.3 POSIX字符类

在一些编程语言和工具中,还支持POSIX字符类,它们是预定义的一些字符类,用于匹配特定类型的字符。

  • [:alnum:]:匹配所有字母和数字字符,等同于[a-zA-Z0-9]

  • [:alpha:]:匹配所有字母字符,等同于[a-zA-Z]

  • [:digit:]:匹配所有数字字符,等同于[0-9]

  • [:lower:]:匹配所有小写字母字符,等同于[a-z]

  • [:upper:]:匹配所有大写字母字符,等同于[A-Z]

  • [:punct:]:匹配所有标点符号字符。

  • [:space:]:匹配所有空白字符,等同于\s

示例:字符类的使用

import re# 匹配所有小写字母
pattern = r'[a-z]'
text = "Hello World!"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']# 匹配所有数字字符
pattern = r'\d'
text = "Contact: 123-456-7890"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']# 使用POSIX字符类匹配所有字母字符
pattern = r'[[:alpha:]]'
text = "Regex 101!"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['R', 'e', 'g', 'e', 'x']

2.6.4 组合使用

字符类可以与其他正则表达式元素结合使用,形成更加复杂的匹配模式。

# 匹配由字母和数字组成的字符串
pattern = r'\w+'
text = "User123 logged in."
matches = re.findall(pattern, text)
print(matches)  # 输出: ['User123', 'logged', 'in']# 匹配以小写字母开头且后面跟着数字的字符串
pattern = r'[a-z]\d+'
text = "a123 B456 c789"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['a123', 'c789']

三、 正则表达式语法规则

正则表达式的语法规则是构建有效正则表达式的基础。以下是一些常见的语法规则:

  1. 组合:使用|来表示“或”,例如ab|cd可以匹配“ab”或“cd”。
  2. 分组:使用圆括号()来创建子表达式,允许对正则表达式的部分进行分组。
  3. 量词:使用量词来指定模式出现的次数。
  4. 转义特殊字符:使用反斜线\来转义特殊字符,使其作为普通字符匹配。

四、高级特性

正则表达式除了基本的字符匹配和量词之外,还包含一些高级特性,用于构建更为复杂的匹配模式。

4.1 回溯引用(捕获组)

捕获组不仅可以用于分组,还可以在正则表达式的其他部分进行引用。引用捕获组可以通过反斜线加上捕获组的编号来实现。

  • ():用来定义捕获组。
  • \1:表示对第一个捕获组的引用。

示例:匹配重复的单词

import re
pattern = r'\b(\w+)\s+\1\b'
text = "This is a test test string"
match = re.search(pattern, text)
if match:print(f"Matched: {match.group(0)}")  # 输出: 'test test'

4.2 非捕获组

有时我们需要分组但不希望它被捕获用于后续引用,可以使用非捕获组(?:...)

示例:非捕获组的使用

pattern = r'(?:ab|cd)+'
text = "ababcdbcd"
matches = re.findall(pattern, text)
print(matches)  # 输出: ['ababcd', 'bcd']

4.3 贪婪与非贪婪匹配

正则表达式的匹配模式默认是贪婪的,即它会尽可能多地匹配字符。可以通过在量词后加上?来使匹配变为非贪婪的,匹配尽可能少的字符。

示例:贪婪与非贪婪的区别

import retext = "<div>hello</div><div>world</div>"# 贪婪匹配
greedy_pattern = r'<.*>'
greedy_match = re.findall(greedy_pattern, text)
print(greedy_match)  # 输出: ['<div>hello</div><div>world</div>']# 非贪婪匹配
non_greedy_pattern = r'<.*?>'
non_greedy_match = re.findall(non_greedy_pattern, text)
print(non_greedy_match)  # 输出: ['<div>', '</div>', '<div>', '</div>']

4.4 零宽断言

零宽断言用于在不消费字符的情况下进行匹配。它分为正向零宽断言(Lookahead)和反向零宽断言(Lookbehind)。

  • (?=...):正向零宽断言,表示某位置后必须匹配某模式。
  • (?<=...):反向零宽断言,表示某位置前必须匹配某模式。
  • (?!...):负向零宽断言,表示某位置后不能匹配某模式。
  • (?<!...):负向反向零宽断言,表示某位置前不能匹配某模式。

示例:使用零宽断言匹配特定模式

# 匹配'fox'前面是'quick'的单词
pattern = r'(?<=quick\s)fox'
text = "The quick brown fox jumps over the lazy dog"
match = re.search(pattern, text)
if match:print(f"Matched: {match.group(0)}")  # 输出: 'fox'# 匹配'fox'后面跟随'jumps'的单词
pattern = r'fox(?=\sjumps)'
text = "The quick brown fox jumps over the lazy dog"
match = re.search(pattern, text)
if match:print(f"Matched: {match.group(0)}")  # 输出: 'fox'

五、 实战案例

5.1 网页数据抓取

使用正则表达式从HTML中提取特定内容。

代码示例:提取图片地址

import rehtml_content = '''
<img src="image1.png" alt="image1">
<img src="image2.jpg" alt="image2">
<img src="image3.gif" alt="image3">
'''pattern = r'<img src="(.*?)"'
images = re.findall(pattern, html_content)
print(images)  # 输出: ['image1.png', 'image2.jpg', 'image3.gif']

5.2 数据清洗

在数据分析过程中,经常需要对数据进行清洗,去除无关字符或格式化数据。

代码示例:清理电话号码中的特殊字符

import retext = "Call us at (123) 456-7890 or 123.456.7890!"
cleaned_numbers = re.sub(r'[^\d]', '', text)
print(cleaned_numbers)  # 输出: '12345678901234567890'

5.3 提取超链接

从HTML文档中提取所有的超链接。

代码示例:提取所有的URL

import rehtml_content = '''
<a href="http://example.com/page1">Page 1</a>
<a href="https://example.com/page2">Page 2</a>
<a href="http://example.com/page3">Page 3</a>
'''pattern = r'<a href="(.*?)">'
links = re.findall(pattern, html_content)
print(links)  # 输出: ['http://example.com/page1', 'https://example.com/page2', 'http://example.com/page3']

5.4 提取网页中的文本内容

提取HTML标签中的文本内容,如提取所有段落标签

中的文本。

代码示例:提取段落文本

import rehtml_content = '''
<p>This is the first paragraph.</p>
<p>Here is the second paragraph with <a href="#">a link</a>.</p>
<p>And the third paragraph.</p>
'''pattern = r'<p>(.*?)</p>'
paragraphs = re.findall(pattern, html_content, re.DOTALL)
print(paragraphs)  # 输出: ['This is the first paragraph.', 'Here is the second paragraph with <a href="#">a link</a>.', 'And the third paragraph.']

5.5 从JSON数据中提取特定键值对

在处理API返回的JSON数据时,可以使用正则表达式快速提取特定的键值对。

代码示例:提取JSON中的特定值

import rejson_data = '''
{"name": "John Doe","email": "john.doe@example.com","phone": "+123-456-7890","address": "123 Main St, Anytown, USA"
}
'''pattern = r'"phone":\s*"(.*?)"'
phone_number = re.search(pattern, json_data).group(1)
print(phone_number)  # 输出: '+123-456-7890'

5.6 清理HTML标签

清理文本中的HTML标签,提取纯文本内容。

代码示例:去除HTML标签

import rehtml_content = '''
<h1>Title</h1>
<p>This is a <strong>bold</strong> statement.</p>
<p>Here is a <a href="#">link</a> and some <em>italic</em> text.</p>
'''clean_text = re.sub(r'<.*?>', '', html_content)
print(clean_text)  # 输出: 'Title\nThis is a bold statement.\nHere is a link and some italic text.'

六、 总结

本文详细介绍了正则表达式的基础知识、语法规则及高级特性,并结合实际案例展示了正则表达式在编程中的重要作用。通过掌握正则表达式,你可以更高效地处理文本数据,解决各种复杂的字符串匹配问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/52438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用ssm实现亿互游在线平台设计与开发+vue

TOC ssm118亿互游在线平台设计与开发vue 绪论 1.1研究背景 时代的发展&#xff0c;我们迎来了数字化信息时代&#xff0c;它正在渐渐的改变着人们的工作、学习以及娱乐方式。计算机网络&#xff0c;Internet扮演着越来越重要的角色&#xff0c;人们已经离不开网络了&#x…

2024世界机器人大会盛大开幕,卓翼飞思携无人智能领域产品集中亮相 !

开放创新 聚享未来&#xff01;万众瞩目的2024世界机器人大会暨博览会于8月21日在北京亦创国际会展中心盛大开幕。大会聚焦机器人技术与产业前沿趋势&#xff0c;展示机器人创新应用赋能千行百业的多元场景&#xff0c;全球顶尖的机器人科学家、行业领袖、创新精英汇聚一堂&…

Pandas教程:使用Pandas合并多个Excel文件

目录 1. 环境准备 1.1 安装Pandas 1.2 准备工作 2. 基本概念 2.1 Pandas简介 2.2 DataFrame的基本操作 3. 读取Excel文件 4. 合并多个Excel文件 4.1 获取文件列表 4.2 读取并合并数据 4.3 处理重复数据 5. 数据存储 6. 完整示例代码 7.代码优化 7.1用类去重新组…

vue3动态引入图片不显示问题

方法1.(打包后动态引用的图片未被打包入工程中,webpack,vite) 1.图片放到public 目录会更省事&#xff0c;不管是开发环境还是生产环境&#xff0c;可以始终以根目录保持图片路径的一致. 假设&#xff1a; 静态文件目录&#xff1a;src/assets/images/ 我们的目标静态文件在 …

Python实现打印http请求信息例子解析

示例代码 import http.clientdef print_http_info(host, path):conn http.client.HTTPConnection(host)method GETurl pathprint(f"{- * 30} 请求信息 {- * 30}")print(f"主机: {host}")print(f"方法: {method}")print(f"URL: {url}&qu…

深入理解Spring Boot日志框架与配置

目录 Spring Boot日志框架概述Spring Boot默认日志框架&#xff1a;Logback日志配置文件日志级别的调整日志输出配置日志格式化日志轮转和归档集成其他日志框架日志管理工具最佳实践总结 Spring Boot日志框架概述 Spring Boot 支持多种日志框架&#xff0c;如 Logback、Log4…

使用HAL库实现按键控制LED和蜂鸣器

下载STM32CubeMX实现项目的初始配置&#xff08;寄存器操作)&#xff0c;下载keil对程序进行编译烧写 在STM32CubeMX中将PB0/PB1设置为输入引脚作为按键&#xff0c;PA6/PA4设置为输出引脚作为led和Beep&#xff0c;将按键引脚设置为上拉输入&#xff1a; 创建项目完成后在kei…

【jvm】程序计数器的特征

目录 1. 说明2. 线程私有3. 存储指令地址4. 不会发生内存溢出5. 生命周期与线程相同 1. 说明 1.JVM&#xff08;Java虚拟机&#xff09;中的程序计数器&#xff08;Program Counter Register&#xff09;&#xff0c;简称PC寄存器&#xff0c;具有几个显著的特征&#xff0c;这…

C语言 | Leetcode C语言题解之第365题水壶问题

题目&#xff1a; 题解&#xff1a; bool canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) {int j1 jug1Capacity < jug2Capacity ? jug1Capacity : jug2Capacity, j2 jug1Capacity > jug2Capacity ? jug1Capacity : jug2Capacity;if (ta…

Umi-OCR 文字识别工具

免费开源的离线orc识别功能 git地址 感谢大佬的贡献 Umi-OCR 文字识别工具 使用说明 • 下载地址 • 更新日志 • 提交Bug 免费&#xff0c;开源&#xff0c;可批量的离线OCR软件 适用于 Windows7 x64 、Linux x64 免费&#xff1a;本项目所有代码开源&#x…

推荐系统三十六式学习笔记:产品篇36 | 组建推荐团队及工程师的学习路径

目录 团队组建个人成长总结 如果你是老板&#xff0c;或者是公司里的推荐系统包工头&#xff0c;那么你一定会关心&#xff1a;要凑齐多少人才能开始搬砖&#xff1f; 一个推荐系统复杂度没有上限&#xff0c;但是有最低标准&#xff0c;所以下面在估算推荐系统团队规模时&…

SpringBoot (面试篇)

什么是SpringBoot 通过SpringBoot&#xff0c;可以轻松的创建独立的&#xff0c;基于生产级别的Spring的应用程序&#xff0c;您可以“运行”它们。大多数SpringBoot应用程序要最少的Sprig配置 为什么要用SpringBoot 快速开发 快速整合 配置简化 内嵌服务容器 SpringBoot与…

Verilog刷题笔记59

题目: Exams/m2014 q6c 解题&#xff1a; module top_module (input [6:1] y,input w,output Y2,output Y4);assign Y2y[1]&w0;assign Y4(y[2]&w1)|(y[3]&w1)|(y[5]&w1)|(y[6]&w1);endmodule结果正确: 注意点: 起初&#xff0c;我的代码有错误,代码如下…

9 正则表达式:Java爬虫和正则表达式、String中的正则表达式方法(基本语法7)

文章目录 前言一、正则表达式1 [ ] 语法(1)[ABC] 和 [^ABC](2)[A-Z]和[a-zA-Z]小总结2 特殊字符语法(\w 这些)3 数量符4 \ 、()、 |5 锚点 ^ 和 $,\b,\B6 (?i) : 忽略其后面的大小写 ---- 这个Java是可以的,其他语言我不知道(正则表达式虽然大多通用,但也有部分是…

视频检索技术为电子商务直播领域带来了前所未有的革新

视频检测在这个场景中指的是通过视频流实时识别和检索直播中销售人员展示的商品。这涉及到从连续的视频帧中分析和识别商品的视觉内容&#xff0c;通常与语音和文本数据结合&#xff0c;以提高识别准确性。 技术原理 文本引导的注意机制&#xff1a;这一机制通过直播中销售人员…

Prometheus学习

监控架构介绍&#xff1a; 基本架构&#xff1a; Prometheus 和 Zabbix 的对比&#xff1a; 安装和使用&#xff1a; Prometheus 采集、存储数据Grafana 用于图表展示alertmanager 用于接收 Prometheus 发送的警告信息node-exporter 用于收集操作系统和硬件信息的 metrics …

猫头虎 分享:Python库 Matplotlib 的简介、安装、用法详解入门教程

&#x1f42f; 猫头虎 分享&#xff1a;Python库 Matplotlib 的简介、安装、用法详解入门教程 今天猫头虎 带大家一起探索一个非常重要的 Python 库——Matplotlib。这是一个强大的工具&#xff0c;广泛应用于数据科学、人工智能和机器学习等领域&#xff0c;用于创建静态、动…

Node.js中的pipe方法:深入解析与应用指南

在Node.js中&#xff0c;pipe方法是处理流&#xff08;Stream&#xff09;数据的一种非常高效的方式。它允许你将一个可读流&#xff08;Readable Stream&#xff09;的数据直接传输到一个可写流&#xff08;Writable Stream&#xff09;中&#xff0c;而无需手动编写读取和写入…

3、springboot时代背景

一、微服务 二、分布式 三、云原生 原生应用如何上云。 Cloud Native 上云的困难 服务自愈弹性伸缩服务隔离自动化部署灰度发布流量治理...... 上云的解决

怎样更改电脑的MAC地址?

怎样更改电脑的MAC地址&#xff1f; 电脑的机器码是可以修改的。 操作步骤&#xff1a; 1、通过按WINR键&#xff0c;调来电脑的接运行窗口&#xff0c;打开CMD命令来查看机器码。 2、命令提示符窗口里输入ipconfig /all&#xff0c;回车&#xff0c;即可显示出当前电脑的网…