(python)正则表达式提取字符串中的各种信息(持续更新)

前言

        在日常数据处理过程,拿到一段文字,进行关键信息的提取.总而言之,翻来覆去地用到几种处理方法.这些都需要用到正则去进行通用处理.比如提取关键信息,诸如时间,日期,地址等.

那么我们要根据关键信息的特征去提取.

函数方法

# 匹配
re.match(pattern, string, flags=0)

# 查找 单个
re.search(pattern, string, flags=0)

# 替换
re.sub(pattern, repl, string, count=0, flags=0)

# 查找 多个 返回列表
re.findall(pattern, string, flags=0)    pattern.findall(string[, pos[, endpos]])

# 查找 多个 返回迭代器
re.finditer(pattern, string, flags=0)

# 拆分
re.split(pattern, string[, maxsplit=0, flags=0])

提取内容

  1. 数字提取:可以用正则表达式来提取数字,包括整数、浮点数等。
  2. 日期和时间提取:可以用正则表达式来提取日期、时间等。
  3. URL 提取:可以用正则表达式从字符串中提取 URL 地址。
  4. 邮件地址提取:可以用正则表达式从字符串中提取邮件地址。
  5. IP 地址提取:可以用正则表达式从字符串中提取 IP 地址。
  6. HTML 标签提取:可以用正则表达式从字符串中提取 HTML 标签。
  7. 手机号码提取:可以用正则表达式从字符串中提取手机号码。
  8. 邮政编码提取:可以用正则表达式从字符串中提取邮政编码。
  9. 特定格式的文本提取:可以用正则表达式从字符串中提取特定格式的文本,如身份证号码、车牌号码等。
  10. 公司简称和股票代码

应用场景

数字提取:可以用正则表达式来提取数字,包括整数、浮点数等。

整数
import re

text = "I have 10 apples and 5 oranges."

# 匹配整数的正则表达式
pattern = r'\d+'  

numbers = re.findall(r'\d+', text)

print(numbers) # [10, 5]
浮点数
import re

text = "这是一个浮点数:3.14"

# 匹配浮点数的正则表达式
pattern = r"\d+\.\d+"  

match = re.search(pattern, text)
if match:
    float_number = float(match.group())
    print(float_number) # 3.14
else:
    print("未找到浮点数")

日期和时间提取

日期
def get_date_text(text):
    """
    处理逻辑:
        年 4位有效数值 \d{4}
        月 0-12   \d{1,2}
        日 0-31   \d{1,2}
    """
    date_text = ""
    if isinstance(text, str):
        regex_rule = r"(\d{4}-\d{1,2}-\d{1,2})"
        regex_pattern = re.compile(regex_rule)
        date_list = regex_pattern.findall(text)
        if date_list:
            date_text = date_list[0]
    return date_text
时间
"""
处理逻辑:
    时间的有效范围
    时 0-23 <-> (0?[0-9]|1[0-9]|2[0-3])
    分 0-59 <-> ([0-5][0-9]|0?[0-9])
    秒 0-59 <-> ([0-5][0-9]|0?[0-9])
"""


def get_time_text(data):
    regex_rule = r'(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])'
    regex_pattern = re.compile(regex_rule)
    ret_list = regex_pattern.findall(data)
    if ret_list:
        return ret_list
    else:
        print('没有匹配成功.')
    return None

# 时间处理
time_str = "升旗时间从05:30:56改成6:00:00"
print(get_time_text(time_str))  # [('05', '30', '56'), ('6', '00', '00')]

URL提取

import re

# 定义一个正则表达式模式来匹配URL
pattern = r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'

# 要匹配的文本
text = '这是一个网站的链接:https://www.example.com,还有一个URL:http://www.google.com'

# 使用re.findall()函数找到所有匹配的URL
urls = re.findall(pattern, text)

# urls = ["https://www.example.com", "http://www.google.com"]
# 打印结果
for url in urls:
    print(url)

邮件地址提取

email = "abcd@mail.com"

pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
if re.match(pattern, email):
   print("有效的邮件地址")
else:
   print("无效的邮件地址")

IP 地址提取

import re

ip_address = "255.255.255.255"
# 定义 IPv4 地址的正则表达式
ipv4_pattern = r'^((25[0-5]|2[0-4]\d|[01]?\d{1,2})\.){3}(25[0-5]|2[0-4]\d|[01]?\d{1,2})$'

# 定义 IPv6 地址的正则表达式
ipv6_pattern = r'^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$'

if re.match(ipv4_pattern, ip_address):
    print("IPv4 地址")
elif re.match(ipv6_pattern, ip_address):
    print("IPv6 地址")
else:
    print("无效的 IP 地址")

HTML 标签提取

import re

def extract_tags(text):
    pattern = r"<([^>]+)>"
    tags = re.findall(pattern, text)
    return tags

html_text = "<html><head><title>Sample Title</title></head><body><h1>Heading</h1><p>Paragraph</p></body></html>"
tags = extract_tags(html_text)
print(tags)
# ['html', 'head', 'title', '/title', '/head', 'body', 'h1', '/h1',
# 'p', '/p', '/body', '/html']

手机号码提取

手机号码有自己特定的特征,比如1开头,手机号码长度 11位,

不同运营商的号段分布

  1. 中国移动:139、138、137、136、135、134、159、158、157、150、151、152、147、182、183、184、187、188等段号码。

  2. 中国联通:130、131、132、155、156、185、186等段号码。

  3. 中国电信:133、153、180、181、189等段号码。

import re

phone_numbers = [
    '13812345678',
    '15887654321',
    '12345678901',
    '98765432109'
]

# 匹配以1开头,第二位是3、4、5、6、7、8或9,后面有9位数字的手机号码。
pattern = r'^1[3456789]\d{9}$'

for number in phone_numbers:
    if re.match(pattern, number):
        print(f'{number} 是有效的手机号码')
    else:
        print(f'{number} 不是有效的手机号码')

邮政编码提取

一般来说,中国的邮政编码由6位数字组成。

PPSSXX

省级行政区 市级行政区 县级行政区

前两位数字代表省级行政区,中间两位数字代表市级行政区,后两位数字代表县级行政区、县市辖区或直辖市的行政区划。

postcode = "123456"
pattern = r'^\d{6}$'  # 匹配6位数字
if re.match(pattern, postcode):
   print("邮政编码有效!")
else:
   print("邮政编码无效!")

身份证号码提取

18 位身份证

DDDDDD YYYYMMDD XXX Y

行政区划代码 出生日期码 顺序码 校验码

身份证号码编写规则是根据中华人民共和国国家标准《GB 11643-1999 公民身份证号码》进行制定的。该编写规则如下:

  1. 身份证号码由18位字符组成,前17位为数字,最后一位可以是数字或字母X(大小写均可)。
  2. 身份证号码的前6位是行政区划代码,表示该身份证持有人所在地区的行政区划。
  3. 接着的8位为出生日期码,格式为年(4位)月(2位)日(2位),表示持有人的出生年月日。
  4. 紧接着的3位为顺序码,表示在同一地区、同一日期出生的人员顺序编号。
  5. 最后一位为校验码,用于校验身份证号码的正确性。
import re
id_number = "51321543212315123"
pattern = r'^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}[0-9Xx]$'
match = re.match(pattern, id_number)
if match:
    print("身份证号码合法!")
else:
    print("身份证号码不合法!")

公司简称和股票代码

公司简称都是中文

股票代码基本上都是6位数

import re

text = "工商银行(600886)\n\t 贵州茅台(000123)"

# 提取公司简称
company_name_pattern = r"[\u4e00-\u9fff]+"
company_name_matches = re.findall(company_name_pattern, text)
company_name = company_name_matches if company_name_matches else None

# 提取证券代码 6位数
stock_code_pattern = r"\d{6}"
stock_code_matches = re.findall(stock_code_pattern, text)
stock_code = stock_code_matches if stock_code_matches else None

print("公司简称:", company_name)  # 公司简称: ['工商银行', '贵州茅台']
print("证券代码:", stock_code)  # 证券代码: ['600886', '000123']

总结 

在使用 Python 正则表达式进行文本提取时,需要注意以下几点:

  1. 正则表达式的语法和规则:熟悉正则表达式的语法和规则是进行文本提取的基础。

  2. 匹配模式和函数:Python 的正则表达式支持多种匹配模式和函数,需要根据需求选择正确的匹配方式和函数。

  3. 字符编码和转义:在处理字符串时,需要注意字符串的编码和转义问题,以避免出现与预期不同的结果。

  4. 贪婪和非贪婪匹配:正则表达式默认采用贪婪匹配模式,可能会导致匹配结果不准确,需要使用非贪婪匹配来避免这种情况。

  5. 匹配结果和分组:在匹配文本时,需要注意匹配结果和各个分组的内容和顺序,以便后续处理和使用。

  6. 异常情况处理:在处理文本时,可能会出现一些异常情况,如无法匹配、匹配结果为空等情况,需要进行适当的异常处理。

  7. 性能优化:在处理大量文本时,需要考虑正则表达式的性能问题,可以通过优化正则表达式和使用预编译对象等方式进行提升。

        总之,在使用 Python 正则表达式进行文本提取时,需要注意正则表达式的语法和规则、匹配模式和函数、字符编码和转义、贪婪和非贪婪匹配、异常情况处理、匹配结果和分组,以及性能优化等方面,以便获得准确、高效的文本提取结果。       

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年11月29日
下一篇 2023年11月29日

相关推荐