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

news2024/9/23 3:25:47

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 re

text = "<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 re

html_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 re

text = "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 re

html_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 re

html_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 re

json_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 re

html_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.coloradmin.cn/o/2068582.html

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

相关文章

用Python移除PowerPoint演示文稿中的所有超链接

在某些PPT使用场景中&#xff0c;比如需要打印幻灯片或者超链接已失效时&#xff0c;演示文稿中的超链接可能会成为一种干扰。这时我们需要移除PowerPoint演示文稿中的超链接&#xff0c;以确保演示的连贯性和专业性。通过使用Python&#xff0c;我们可以高效地批量处理这一任务…

Java | Leetcode Java题解之第365题水壶问题

题目&#xff1a; 题解&#xff1a; class Solution {public boolean canMeasureWater(int x, int y, int z) {if (x y < z) {return false;}if (x 0 || y 0) {return z 0 || x y z;}return z % gcd(x, y) 0;}public int gcd(int x, int y) {int remainder x % y;w…

提升录制效率,这些录屏软件快捷键你不可不知

我们工作、学习及娱乐中不可或缺的工具有很多&#xff0c;别的不知道肯定有录屏工具的一席之地吧。如果平常频繁的使用这个工具想要它更高效那不妨试试使用录屏快捷键&#xff0c;这次我们来讨论下大家都在用的那些录屏工具吧。 1.福昕录屏大师 链接&#xff1a;www.foxitsof…

案例分享—国外简洁UI设计界面赏析

简洁的页面遵循“少即是多”的设计哲学&#xff0c;强调通过精简元素、色彩和布局来突出核心功能&#xff0c;使设计作品更加直观易用&#xff0c;提升用户体验&#xff1b; 深受现代主义与极简主义思潮影响&#xff0c;这些流派鼓励去除冗余&#xff0c;追求形式与功能的完美结…

Stable Diffusion 与 DALL·E3 的深度解析

一、Stable Diffusion 的全方位解读 Stable Diffusion 是一款令人瞩目的 AI 绘画工具&#xff0c;其显著特点之一便是开源免费。这意味着用户无需支付费用即可自由使用和修改&#xff0c;为广大创作者提供了极大的便利。然而&#xff0c;要想充分发挥其功能&#xff0c;对电脑…

鸿蒙Harmony编程开发:HTTPS服务端证书四种校验方式

如果你还是使用HttpRequest的话&#xff0c;答案是否定的。但是&#xff0c;鸿蒙开发者很贴心的推出了远场通信服务&#xff0c;可以使用rcp模块的方法发起请求&#xff0c;并且在请求时指定服务端证书的验证方式&#xff0c;关键点就在SecurityConfiguration接口上&#xff0c…

K8S故障排查可视化指南 —— 筑梦之路

在线查看 中文版&#xff1a;http://114.132.181.71:8080/book/71 英文版&#xff1a;http://114.132.181.71:8080/book/70 A visual guide on troubleshooting Kubernetes deployments

Python二级(易错点讲解)

今天在做真题时&#xff0c;遇到了不少坑的地方&#xff0c;跟大家一起分享&#xff0c;感谢大家观看和关注。 祝大家都能在20多天后顺利通过Python二级。 一.continue循环 大家都知道continue关键字在编程中用于跳过当前循环的剩余迭代并直接开始下一次迭代。 好&#xff0c;…

怎么整合spring security和JWT

什么是spring security spring security是一个安全框架,它里面有过滤器链,可以多次过滤,其实他可以给前端的cookie传入一个jsessionid,都可以不使用jwt也能完成校验 第一步:导入依赖 <!-- springboot security --> <dependency><groupId>org.springframew…

整合Spring和Mybatis(在整合DBCP基础上修改)

整合DBCP请参考主页文章spring整合DBCP 前期准备工作 删除dao层的实现类&#xff0c;只留下接口即可。 在resource文件夹下导入dao层对应的xml文件以及mybatis的核心配置文件&#xff0c;配置文件中只写加载映射文件的代码即可&#xff0c;如下所示 <?xml version"…

Kakfa的核心概念-Replica副本(kafka创建topic并指定分区和副本的两种方式)

Kakfa的核心概念-Replica副本&#xff08;kafka创建topic并指定分区和副本的两种方式&#xff09; 1、kafka命令行脚本创建topic并指定分区和副本2、springboot集成kafka创建topic并指定分区和副本2.1、springboot集成kafka2.1.1、springboot集成kafka创建topic并指定5个分区和…

java BIO NIO AIO

结合JavaGuideIO部分内容食用更佳 在Java中&#xff0c;I/O&#xff08;输入/输出&#xff09;操作主要有三种模型&#xff1a;BIO&#xff08;Blocking I/O&#xff0c;阻塞I/O&#xff09;、NIO&#xff08;Non-blocking I/O&#xff0c;非阻塞I/O&#xff09;和AIO&#x…

怎样写好提示词(Prompt) 一

提示工程是一门新兴的学科&#xff0c;专注于以最佳实践构建LLM的最佳输入&#xff0c;从而尽可能以程序化方式生成目标输出。AI工程师必须知道如何与AI进行交互&#xff0c;以获取可用于应用程序的有利结果。此外&#xff0c;AI工程师还必须知道如何正确提问和编写高质量的提示…

python小游戏——躲避球(可当课设)

游戏简介&#xff1a; 没有美术&#xff0c;画面简洁&#xff08;懒得做&#xff09;。玩家控制小球躲避敌人&#xff08;上下左右&#xff0c;闪避&#xff09;&#xff0c;敌人体积越大速度越慢&#xff0c;随机生成道具球&#xff08;目前只有生命球&#xff09;&#xff0…

第T9周:猫狗识别2

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊](K同学啊)** 一、前期工作 1. 设置GPU import tensorflow as tfgpus tf.config.list_physical_devices("GPU")if gpus:t…

Linux权限概念与思想,能深度理解“权限”,看这一篇就够啦

目录 一、Linux权限的概念 a.什么是权限&#xff1f; b.权限的本质 c.Linux中的用户 1.从root用户切换到普通用户user&#xff1a; 2.从普通用户user切换到root用户&#xff1a; 3.我不想直接变成root&#xff0c;但是我就是想以root的身份执行一个工作&#xff1f; 4.L…

EXCEL 分组后找出满足条件的行拼接起来

Excel某表格有四列&#xff0c;其中第2列是分组列。 ABCD11a1yet22a2done33a3yet44b1done55b2done66b3done77b4yet88b5done 现在要按第2列分组&#xff0c;找到每组第4列等于"done"的行&#xff0c;将这些行的第3列用逗号拼起来&#xff0c;再与分组名、行号组成新…

Unity动画模块 之 动画层混合

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 1.动画层 动画层 - Unity 手册&#xff0c;动画层的作用 混合模式 覆盖和叠加模式&#xff0c;很好理解吧 权重 到底…

若依权限控制前端+后端实现思路梳理(PreAuthorize、hasPermi、v-hasPermi)

一、权限控制引发的思考 引言 最近接手了公司的一个项目&#xff0c;实施反馈说&#xff0c;客户那边要求对不同的权限的用户操作权限做限制。场景就是&#xff0c;比如一个项目列表&#xff0c;这部分数据有可能是针对某个公司某个部门的&#xff0c;对应不同的部门用户能看…

云岚到家 第一天

你的项目是做什么业务的&#xff1f; 家政服务&#xff0c;我的项目是一个家政o2o平台。o2o&#xff08;Online To Offline&#xff09;是将线下商务的机会与互联网的技术结合 什么商业模式&#xff1a; 项目涉及哪些角色&#xff1f; 本项目涉及如下角色&#xff1a; 家政…