python re 数据正则化匹配--笔记总览

本文介绍了Python正则表达式的基础知识,包括re.findall的用法、数字匹配、元字符、字符集合以及匹配次数的控制。通过案例展示了如何使用正则表达式从CSV数据中提取图像名称、类别、疑似度分数和坐标信息,将字符串数据转化为可处理的数值列表。此外,还提供了取整数和小数的正则表达式示例,以及如何根据已知部分匹配完整字符串的方法。
摘要由CSDN通过智能技术生成

正则表达式,可谓是数据处理的神器,我算是见识到了它的威力。之前也接触过,但一直没有搞明白。今再次接触,定要学个明明白白。算有一些入门了,就分享到此处。一是方便日后自己查找,二是方便小伙伴一起交流学习。日后有更多关于正则化的学习、应用,也将会分享于此。

一:re.findall

在做数据处理的时候,最烦遇到的是一种什么情况呢?

  1. 数据有规律的存储了
  2. 然后存储好的一堆数据,又需要解析出来用
  3. 一组数据里面各种形形色色的格式

如果是CSV文件,读取出来的,都当做字符串。要想取个什么东西,就要按照字符串的处理方式,例如find,split等等,较为繁琐。但是,正则化就显得尤为的简单,然而,这就需要找到数据中的一般规律,然后用re取出来,这个流程就较为的简单了。

本小节主要知识点如下:

  1. re.findall 在字符串中返回正则表达式所匹配的的所有子串,并返回一个列表。如果一个都没有匹配上,则返回空列表
  2. \d 匹配字符串中的数字
  3. *  重复0次或更多次  例如:35.26  35 + . + 26  [0-9] + . + [0-9]
  4. 真 . 需加 \ ,即 \.;当然,要查找\本身,你也得用\\

正则匹配中的元字符有: . ^ $ * + ? { [ ] \ | ( )。这些元字符的主要作用是跟其它的标准字符一起组成匹配的规则,所以可以认为它们是带有其它作用的特殊字符。

 匹配字符的规则

(1)通过正反括号"["和"]"确定要匹配的字符

         “[]”这个括号里面可以例举出想要匹配的字符集合,也可以通过限定字符集的范围确定。例如,[abc] 和[a-c]都表示匹配"a", "b", 或 "c"中的任意一个字符。

        如果字符本身是元字符,那么它在 “[]”里面的时候就是一个普通字符,例如:[[]就是表示匹配字符“[”。

(2)取反元字符 ^ 的使用

        在方括号中,首字符如果使用取反字符^的话,就表示匹配初括号中的字符之外的其它字符。例如,[^5] 将匹配除 "5" 之外的任意字符。

(3)反斜杠“\”的使用

作用1:将那些在正则匹配中有特殊意义的字符转换成普通的字符,或者将普通字符标记成它代表的特殊意义

作用2:用来确定要匹配的字符类型,规则如下:

\d  匹配任何十进制数;它相当于类 [0-9]。
\D  匹配任何非数字字符;它相当于类 [^0-9]。


\s  匹配任何空白字符;它相当于类  [ \t\n\r\f\v]。
\S  匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。


\w  匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W  匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。

匹配字符的个数

        re中主要使用*、+、?还有花括号{}来确定匹配的字符的个数

(1)* 指定前一个字符可以被匹配零次或更多次,而不是只有一次。ca*t 将匹配 "ct" (0 个 "a" 字符), "cat" (1 个 "a"), "caaat" (3 个 "a" 字符)等等

(2)+ 表示匹配一或更多次。用同一个例子,ca+t 就可以匹配 "cat" (1 个 "a"), "caaat" (3 个 "a"), 但不能匹配 "ct"。

(3)?  匹配一次或零次;你可以认为它用于标识某事物是可选的。例如:home-?brew 匹配 "homebrew" 或 "home-brew"。

(4){m,n},其中 m 和 n 是十进制整数。该限定符的意思是至少有 m 个重复,至多到 n 个重复。举个例子,a/{1,3}b 将匹配 "a/b","a//b" 和 "a///b"。它不能匹配 "ab" 因为没有斜杠,也不能匹配 "ab" ,因为有四个。

光说不练假把式。下面,就用一个案例,来将上面四点,做个实践。上面4点看不懂的不要紧,下面的案例包你看明白,为你初入正则化,做开门解惑。

案例:今有一张数据统计表,数据存储为CSV格式,数据共四列(没看到四列的,光标放到表格里面,向右移动,即可看到),内容如下:

ddaae641bf2af78c1a02ba43575b0d51_3001_2849_0.1440486666667_0.1440486666667.png[0][0.6761001944541931][[273.28466796875, 175.67626953125, 402.2430419921875, 328.661865234375]]
2.25.136083661060415706315254052090742684427_4000_3000_0_0.png[0, 0][0.7710305452346802, 0.5624949932098389][[190.70089721679688, 38.103851318359375, 450.9465637207031, 446.1026916503906], [615.7803955078125, 33.51222229003906, 808.9849853515625, 279.001953125]]
2.25.325405860827049753751982304033775186562_3370_3214_0_0.png[0, 0, 0][0.8847285509109497, 0.7925058603286743, 0.5061626434326172][[61.759857177734375, 317.8360595703125, 316.9251708984375, 758.53271484375], [119.5316162109375, 86.29457092285156, 465.26458740234375, 359.308349609375], [676.3946533203125, 208.73971557617188, 899.0660400390625, 524.486328125]]

 截图的样子如下 ,下面这个表格截图看着直观些:

 做AI图像这块的,应该很容易可以看出来,这四列是有具体含义的。我这是做目标检测任务,四列分别是:

  1. 图像名
  2. 标签0 or 1 list
  3. 疑似度分数 list
  4. 目标框的坐标 list

后面,我们看看操作过程:(不为什么目的,就学习数据的正则化)

import pandas as pd
import re
import numpy as np

my_csv_path = r'tb.csv'

content = pd.read_csv(my_csv_path, delimiter=',', header=None, index_col=False)

name = content[0].values     # 第一列,文件名
pcls = content[1].values      # 第二列,类别
scores = content[2].values    # 第三列,分数
bbox = content[3].values      # 第四列,坐标

# re.findall在字符串中返回正则表达式所匹配的的所有子串,并返回一个列表。如果一个都没有匹配上,则返回空列表。
# \d 匹配字符串中的数字
# * 重复0次或更多次  例如:35.26  35+.+26  [0-9]+.+[0-9] 真.需加\,即\.
def cls2list(i):
    print("i:", i)
    # \d 匹配数字 [0, 0]
    cls_str = re.findall("(\d)",i)
    print("cls_str:", cls_str)
    cls_list = [float(i) for i in cls_str]
    print("cls_list:", cls_list)
    print("cls_list.type:", type(cls_list))
    return cls_list

def score2list(i):
    # \d 匹配数字,真.需加\,即\.
    # 例如:[0.7710305452346802, 0.5624949932098389]  0 + . + 7710305452346802
    print("i:", i)
    score_str = re.findall("(\d*\.\d*)",i)
    print("score_str:", score_str)
    score_list = [float(i) for i in score_str]
    
    # box_list = np.array(box_list).reshape(-1, 2)        改变形状
    
    print("score_list:", score_list)
    print("score_list.type:", type(score_list))
    return score_list

def box2list(i):
    """
    :param i: 一張圖片中文本類型的box xmin,ymin,xmax,ymax
    :return: 二維數組描述框
    """
    print(i)
    # [0-9] 匹配字符串中的所有数字
    # * 重复0次或更多次  例如:35.26  35+.+26  [0-9]+.+[0-9] 真.需加\,即\.
    box_str = re.findall("([0-9]*\.[0-9]*)", i)        # 只能分数
    # box_str = re.findall(r'\d+(?:\.\d+)?', i)          # 分数和整数都行
    print("box_str:", box_str)
    box_list =[float(i) for i in box_str]
    print("box_list:", box_list)
    print("box_list.type:", type(box_list))
    return box_list

for i in range(2):
    name_i = name[i]
    cls_i = pcls[i]
    scores_i = scores[i]
    bboxes_i = bbox[i]

    print(name_i, cls_i, scores_i, bboxes_i)
    print(type(name_i), type(cls_i), type(scores_i), type(bboxes_i))

    # 1.对cls做数据正则化  [0, 0]
    cls_i_list = cls2list(cls_i)
    print("\n")

    # 2.对score做数据正则化 ['0.7710305452346802', '0.5624949932098389']
    score_i_list = score2list(scores_i)
    print("\n")

    # 3.对bbox做数据正则化
    # [[190.70089721679688, 38.103851318359375, 450.9465637207031, 446.1026916503906],
    # [615.7803955078125, 33.51222229003906, 808.9849853515625, 279.001953125]]
    bbox_i_list = box2list(bboxes_i)
    print("\n")

打印的结果显示如下:

ddaae641bf2af78c1a02ba43575b0d51_3001_2849_0.1440486666667_0.1440486666667.png [0] [0.6761001944541931] [[273.28466796875, 175.67626953125, 402.2430419921875, 328.661865234375]]
<class 'str'> <class 'str'> <class 'str'> <class 'str'>
i: [0]
cls_str: ['0']
cls_list: [0.0]
cls_list.type: <class 'list'>


i: [0.6761001944541931]
score_str: ['0.6761001944541931']
score_list: [0.6761001944541931]
score_list.type: <class 'list'>


[[273.28466796875, 175.67626953125, 402.2430419921875, 328.661865234375]]
box_str: ['273.28466796875', '175.67626953125', '402.2430419921875', '328.661865234375']
box_list: [273.28466796875, 175.67626953125, 402.2430419921875, 328.661865234375]
box_list.type: <class 'list'>


2.25.136083661060415706315254052090742684427_4000_3000_0_0.png [0, 0] [0.7710305452346802, 0.5624949932098389] [[190.70089721679688, 38.103851318359375, 450.9465637207031, 446.1026916503906], [615.7803955078125, 33.51222229003906, 808.9849853515625, 279.001953125]]
<class 'str'> <class 'str'> <class 'str'> <class 'str'>
i: [0, 0]
cls_str: ['0', '0']
cls_list: [0.0, 0.0]
cls_list.type: <class 'list'>


i: [0.7710305452346802, 0.5624949932098389]
score_str: ['0.7710305452346802', '0.5624949932098389']
score_list: [0.7710305452346802, 0.5624949932098389]
score_list.type: <class 'list'>


[[190.70089721679688, 38.103851318359375, 450.9465637207031, 446.1026916503906], [615.7803955078125, 33.51222229003906, 808.9849853515625, 279.001953125]]
box_str: ['190.70089721679688', '38.103851318359375', '450.9465637207031', '446.1026916503906', '615.7803955078125', '33.51222229003906', '808.9849853515625', '279.001953125']
box_list: [190.70089721679688, 38.103851318359375, 450.9465637207031, 446.1026916503906, 615.7803955078125, 33.51222229003906, 808.9849853515625, 279.001953125]
box_list.type: <class 'list'>
补充:取整数:value = re.findall("(\d+)", contour_value)    例如:“563,849,698”  
补充:整数或小数,lineArr = re.findall('\d+\.*\d*', contour_value)    例如:56,98,53.635,1296.36598

备注:\d+ 不配小数点前面的
     \.就是.  \.*表示可以匹配0次或多次.   \d*匹配小数点后面的

看明白上面代码里面的注释了吗?思路和过程都打印了出来。

re.findall 在字符串中返回正则表达式所匹配的的所有子串,并返回一个列表。如果一个都没有匹配上,则返回空列表。

  1. 类, [0, 0],单个的数字,用 \d 来做数字匹配。就可以全取出来了,正则表达式为:(\d)
  2. 疑似度分数,[0.984,0.765],拆分来看,是由数字和.(点)组成的,通俗点就是:0 + . + 984,正则表达式为:(\d*\.\d*)
  3. 坐标框,[[273.28466796875, 175.67626953125, 402.2430419921875, 328.661865234375]],拆分来看,是由273 + . +28466796875,正则表达式为:([0-9]*\.[0-9]*),[0-9] 表示匹配字符串中的0-9所有数字,*为多次,\. 就表示为.,后面重复

这就是正则表达式的入门,为有些明白正则表达式其中的内涵了。emeditor文档编辑软件里面,就可以直接在上面进行正则化匹配,方便验证。

后面继续学习,将继续分享到这里。喜欢和感兴趣的,欢迎持续关注和收藏,有任何疑问的,可以在下方留言,一起交流。

补充1:如何取出一组字符串中的数字(整数或小数)

import re
>>> s = '4 and 10.2356'
>>> re.findall(r'\d+(?:\.\d+)?', s)
['4', '10.2356']
>>> print(int(re.findall(r'\d+(?:\.\d+)?', s)[0]))
4
>>> print(float(re.findall(r'\d+(?:\.\d+)?', s)[1]))
10.2356
  • \d+: matches one or more digits.
  • \d+.\d+ :matches one or more digits plus any single character plus one or more digits.
  • \d+.\d+ :matches one or more digit characters pus a literal dot plus one or more digits.
  • \d+(?:.\d+)? :matches integer as well as floating point numbers because we made the pattern which matches the decimal part as optional. ? after a capturing or non-capturing group would turn the whole group to an optional one.

原文链接:https://blog.csdn.net/irober/article/details/107091418

补充二:字符补全

任务:只知道前面,或者中间的字符,想要匹配所有的字符

def re_name(raw_string, cop_string):
    findword = cop_string+r'.\d*'  # 取该字符串以及其后面任意多个数字字符
    pattern = re.compile(findword)
    results = re.findall(pattern, raw_string)
    print(results)
    return results

temp = '1235_5_5, 1235_5_61, 123_5_6,1298'
re_name(temp, cop_string='1235_5_')

输出打印结果:

['1235_5_5', '1235_5_61']

其他类似补充:

def re_name(raw_string, cop_string):
    findword = cop_string+r'.{2}'  # 取该字符串以及其后面2个字符数据
    pattern = re.compile(findword)
    results = re.findall(pattern, raw_string)
    print(results)

temp = '1235_5_5, 1235_5_61, 1235_5_623, 1298'
re_name(temp, cop_string='1235_5_')

output:
['1235_5_5,', '1235_5_61', '1235_5_62']

#######################################################################

def re_name(raw_string, cop_string):
    findword = r'.{1}' + cop_string+r'.{2}'  # 取该字符串以及其后面2个字符数据
    pattern = re.compile(findword)
    results = re.findall(pattern, raw_string)
    print(results)

temp = '1235_5_5, 1235_5_61, 1235_5_623, 1298'
re_name(temp, cop_string='35_5_')

output:
['235_5_5,', '235_5_61', '235_5_62']

#######################################################################

def re_name(raw_string, cop_string):
    findword = cop_string + r'.\d?_\d?_\d?_\d?'  # _2103845659_4_6_1_5.png
    pattern = re.compile(findword)
    results = re.findall(pattern, raw_string)
    print(results)
    return results

temp = '1235_5_5_2_1_1, 1235_5_61_6_3_6, 123_5_6_5, 1298'
re_name(temp, cop_string='1235_5_')

output:
['1235_5_5_2_1_1', '1235_5_61_6_3_6']

参考地址:在Python中使用正则re查找特定字符串、去除重复数据、取固定格式的特定字符串_小白_努力-CSDN博客https://blog.csdn.net/laobai1015/article/details/88541055

 Python用re正则匹配处理字符_u011412768的博客-CSDN博客https://blog.csdn.net/u011412768/article/details/109559870

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钱多多先森

你的鼓励,是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值