首页 > 编程语言 >python之re库,正则表达

python之re库,正则表达

时间:2024-05-26 22:24:39浏览次数:21  
标签:search 匹配 python pattern re 正则 print match

一、前言

为什么要学re库呢?这里主要学他的正则表达,在编写安全脚本的时候肯定要遇到一些不规则的匹配规则,当然编写爬虫也少不了正则匹配去找到一些具有特殊特征的字符串。因此这是十分必要的,然而。re库使 Python 语言拥有全部的正则表达式功能。我会先介绍一些常见的函数的功能并且举例。后再举例说明。一些常见的情况。当然除了掌握函数的功能,这只是基础,重点是自己会构造pattern。

这里介绍的匹配通俗来讲就是在一段字符串里面找某段字符串(pattern),在re库里面就有re.match()和re.search()等一些函数来找。

一定要会使用编译函数comlie(),find_all(),还有会正则表达格式。

二、re.match()

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 none。

规则是
re.match(pattern,string,flag)

举例说明:

import re

print(re.match('www','www.baidu.com'))
print(re.match('www','www.baidu.com').span())
print(re.match('www','ewwww'))

#输出
<re.Match object; span=(0, 3), match='www'> #匹配成功返回一个对象
(0,3)	#只要起始位置到结束
None	#起始位置不匹配。返回空

这里就要提到另外一个知识点,我们知道,re.match返回的是一个obj,其中里面包含了span也就是位置,那我要返回匹配到的字符呢?为什么要返回匹配到的字符呢?因为这里的pattern到后面我们是自己设置的一些模式化的字符,比如我们要在一个js文件里面找出url,那么我们就要编写pattern模式,然后返回这个匹配到的模式字符。

所有这里引出来group()

group()

当使用正则表达式匹配时,通常会定义一个模式,该模式中包含一个或多个用括号括起来的子表达式,这些子表达式被称为"捕获组"。这些捕获组用于从匹配的文本中提取特定部分。例如,考虑以下示例:

import re

text = "My phone number is 123-456-7890."

# 匹配电话号码的模式,使用捕获组提取区号、中间号和最后四位数字
pattern = r'(\d{3})-(\d{3})-(\d{4})'

match = re.search(pattern, text)

if match:
    full_match = match.group(0)  # 整个匹配
    area_code = match.group(1)  # 第一个捕获组
    middle_digits = match.group(2)  # 第二个捕获组
    last_digits = match.group(3)  # 第三个捕获组

    print("Full Match: ", full_match)
    print("Area Code: ", area_code)
    print("Middle Digits: ", middle_digits)
    print("Last Digits: ", last_digits)
else:
    print("No match.")


#结果
Full Match:  123-456-7890
Area Code:  123
Middle Digits:  456
Last Digits:  7890

通俗解释就是:在pattern = r'(\d{3})-(\d{3})-(\d{4})'模式中,有三个捕获组,当匹配到的时候就可以使用group()返回整个匹配到的内容。使用group(1)就可以返回第一个捕获组。

如果要不区分大小写,就把flag设置为 re.M|re.I

例如

re.search(pattern, text,re.M|re.I)

三、re.search()

OK!到这里基本上已经了解到什么是匹配什么是模式,怎么返回匹配到的内容或者位置。现在引入另外一个常见的就是search

通常我们使用的都是这个去匹配而不是使用match;

使用规则
re.search(pattern,string,flag)
与match的区别在于,search是从整个string中查找到pattern,然后返回obj,否则返回none。而match是只从开始找,如果一开始就不匹配那就返回none
import re

pattern = 'ww'
string = 'aww'
string2 = 'wwsdgsdww'
match = re.search(pattern,string)
match2 = re.search(pattern,string2)
print(match)
print(match2)
print(match.group())

#输出

<re.Match object; span=(1, 3), match='ww'>
<re.Match object; span=(0, 2), match='ww'>
ww

四、替换函数re.sub()

 re.sub(pattern, repl, string, count=0, flags=0)
 
 参数:
 
 - pattern : 正则中的模式字符串。
 - repl : 替换的字符串,也可为一个函数。
 - string : 要被查找替换的原始字符串。
 - count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。

举例:

import re

pattern = 'ww'
string2 = 'wwsdgsdww'
replace = re.sub(pattern,"okok",string2)
print(replace)

#结果
okoksdgsdokok

五、编译函数compile()

主要作用就是编译,什么意思?就是将pattern进行编译,在不编译pattern之前,我们是直接把pattern放进函数里面的,那样他会自己编译,但是当我们编译了之后就不用直接调用了。

举例:

import re

pattern = 'ww'
string2 = 'wwsdgsdww'
replace = re.search(pattern,string2)
print(replace)
#使用编译
pattern = re.compile(pattern)
replace = pattern.search(string2)
print(replace)

#输出

<re.Match object; span=(0, 2), match='ww'>
<re.Match object; span=(0, 2), match='ww'>

六、查找函数find_all(),finditer()

与search的区别在于它找到的是多个,返回的是一个列表。

规则:

findall(string[, pos[, endpos]])
比如:
findall(string,0,10)

举例

import re

pattern = 'ww'
string2 = 'wwsdgsdww'
pattern = re.compile(pattern)
result = pattern.findall(string2)
print(result)

#输出
['ww', 'ww']

finditer和find_all一样。只不过finditer返回的是迭代,而不是列表。需要使用for循环print出来。

七、正则表达式

这里很重要,但是知识点又很多,所以看懂就行,建议当要设置匹配某个字符的特征表达式的时候,集合chatgpt来写。

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾。
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...] 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的两个 o。
re 匹配 n 个前面表达式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等价于 "o+"。"o{0,}" 则等价于 "o*"。
re 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b 匹配a或b
(re) 对正则表达式分组并记住匹配的文本
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (...), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释.
(?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re) 匹配的独立模式,省去回溯。
\w 匹配字母数字及下划线
\W 匹配非字母数字及下划线
\s 匹配任意空白字符,等价于 [ \t\n\r\f]
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9].
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等. 匹配一个换行符。匹配一个制表符。等
\1...\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

举例:

在前端的代码中找出url:

import requests,re

# url = "https://ruan0423.github.io/"
url = 'https://www.baidu.com'

js_tewxt = requests.get(url).text
# print(js_tewxt)
pattern_raw = r"""
  (?:"|')                               # Start newline delimiter
  (
    ((?:[a-zA-Z]{1,10}://|//)           # Match a scheme [a-Z]*1-10 or //
    [^"'/]{1,}\.                        # Match a domainname (any character + dot)
    [a-zA-Z]{2,}[^"']{0,})              # The domainextension and/or path
    |
    ((?:/|\.\./|\./)                    # Start with /,../,./
    [^"'><,;| *()(%%$^/\\\[\]]          # Next character can't be...
    [^"'><,;|()]{1,})                   # Rest of the characters can't be
    |
    ([a-zA-Z0-9_\-/]{1,}/               # Relative endpoint with /
    [a-zA-Z0-9_\-/]{1,}                 # Resource name
    \.(?:[a-zA-Z]{1,4}|action)          # Rest + extension (length 1-4 or action)
    (?:[\?|/][^"|']{0,}|))              # ? mark with parameters
    |
    ([a-zA-Z0-9_\-]{1,}                 # filename
    \.(?:php|asp|aspx|jsp|json|
         action|html|js|txt|xml)             # . + extension
    (?:\?[^"|']{0,}|))                  # ? mark with parameters
  )
  (?:"|')                               # End newline delimiter
"""
pattern_raw = re.compile(pattern_raw,re.VERBOSE)

result = pattern_raw.finditer(str(js_tewxt))
# print(result)

for i in result:
    print(i.group())

结果

"http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='

标签:search,匹配,python,pattern,re,正则,print,match
From: https://www.cnblogs.com/iruan/p/18214388

相关文章

  • python脚本之requests库上传文件
    一、前言在学习的时候,发现有一个AWD的文件上传执行漏洞,突然想着批量对不同靶机进行操作并get_flag。思路简单,但是没构造过文件上传的requests的post请求的payload。便记录一下。二、构造知识在上传文件的时候,数据表的post请求体里面通常是下面这样------WebKitFormBoundary......
  • Lakehouse 还是 Warehouse?(1/2)
    Onehouse创始人/首席执行官VinothChandar于2022年3月在奥斯汀数据委员会发表了这一重要演讲。奥斯汀数据委员会是“世界上最大的独立全栈数据会议”,这是一个由社区驱动的活动,包括数据科学、数据工程、分析、机器学习(ML)、人工智能(AI)等。VinothChandar在Uber工作期......
  • 【Python】 XGBoost模型的使用案例及原理解析
    原谅把你带走的雨天在渐渐模糊的窗前每个人最后都要说再见原谅被你带走的永远微笑着容易过一天也许是我已经老了一点那些日子你会不会舍不得思念就像关不紧的门空气里有幸福的灰尘否则为何闭上眼睛的时候又全都想起了谁都别说让我一个人躲一躲你的承诺我竟......
  • 【Python】LightGBM:快速高效的梯度提升框架
    原谅把你带走的雨天在渐渐模糊的窗前每个人最后都要说再见原谅被你带走的永远微笑着容易过一天也许是我已经老了一点那些日子你会不会舍不得思念就像关不紧的门空气里有幸福的灰尘否则为何闭上眼睛的时候又全都想起了谁都别说让我一个人躲一躲你的承诺我竟......
  • 【Python】 XGBoost vs LightGBM:两大梯度提升框架的对比
    原谅把你带走的雨天在渐渐模糊的窗前每个人最后都要说再见原谅被你带走的永远微笑着容易过一天也许是我已经老了一点那些日子你会不会舍不得思念就像关不紧的门空气里有幸福的灰尘否则为何闭上眼睛的时候又全都想起了谁都别说让我一个人躲一躲你的承诺我竟......
  • 【Python】利用TensorFlow和Keras进行不平衡数据集的分类任务
    原谅把你带走的雨天在渐渐模糊的窗前每个人最后都要说再见原谅被你带走的永远微笑着容易过一天也许是我已经老了一点那些日子你会不会舍不得思念就像关不紧的门空气里有幸福的灰尘否则为何闭上眼睛的时候又全都想起了谁都别说让我一个人躲一躲你的承诺我竟......
  • Redis-事务
    简介说到事务,一般都会第一时间的想到MySQL的事务。在MySQL中事务的提出是为了解决解决原子性操作的,一组执行命令要么全部执行成功,要么执行失败进行回滚,一条也不执行。在Redis中也有事务这个概念,但与MySQL相比,就比较弟弟了~Redis实现了个类似的效果,但是不能保证实现MySQL的......
  • HITSC_3_Software Construction Process and Configuration Management
    目标软件开发流程及模式,敏捷开发,软件配置管理SCM,Git,软件构造过程和构造工具SDLC传统软件开发模型瀑布模型线性模型优点:划分阶段,管理简单缺点:不迭代,所以缺少灵活性,也难以适应需求;并且用户看不到原型,导致风险高,前期错误后期发现增量模型瀑布串行,容易适应需求增加V模型......
  • 8-1 【Python0031】简易带参计算器
    设计一个简易的参数计算器。【输入格式】第一行输入待计算的带变量参数的计算式第二行输入各变量参数的赋值序列【输出格式】输出带变量参数的计算式的计算结果【输入样例】a+ba=1,b=10【输出样例】11 defparse_and_compute(expression,values):#创建一个字......
  • 8-3 【Python0035】英文统计
    编写程序实现对特定英文文章(文本文件)的单词数和有效行数的统计,其中要求空行不计数; defcount_words_and_lines(filename):word_count=0line_count=0withopen(filename,'r')asfile:forlineinfile:stripped_line=line.strip()ifs......