当前位置: 首页 > article >正文

NLP DAY2: 文本数据处理(一部分)

事情无论巨细,往往存在一个准备阶段。比如做饭炒菜,需要择菜、洗菜、切菜、热锅等准备工作;出远门需要整理好身份证、手机、钱包等随身物品。类似地,在处理文本的任务中,也存在预处理这么一个重要阶段,包括诸如统一数据格式、去噪、词形还原、分词之类的基本操作,以及语义分析、关键词提取、对于数据不平衡的处理等更进一步的精细处理。

知识点
  • 正则表达式
  • 分词
  • 词性标注
  • 词干提取与词形还原
  • 命名实体识别
  • 文本的数据增强

正则表达式 

 ​​​​​

假设有一天,你的上司给你几百个 txt 文本,并且布置了一个任务,找出文本中所有出现的身份证号以及电话号码,并且要求在一个小时内完成。这时候该怎么办呢?总不可能肉眼一个个地去找吧,太费时了!在这里,正则表达式就派上用场了。学会了正则表达式,你就能在 20 分钟内完成此任务。

正则表达式,又称规则表达式,英语称为 Regular Expression,通常被用来检索、替换那些符合某个模式 (规则) 的文本,例如在以上任务中匹配身份证号或者电话号码,是在文本预处理过程中常用的技术。

那么,正则表达式怎么写呢?在这之前,让我们首先来熟悉一些基本的正则表达式的语法:

  • . :能够匹配除换行符 \n 以外的任意单个字符。
  • \w :与单个字母数字字符匹配。
  • \W :与单个非字母数字字符匹配。
  • \d :与单个数字匹配。
  • \D :与单个非数字匹配。
  • \s :与单个空格字符(空格,换行符,返回符,制表符,表格)匹配。
  • \S :与任何非空格字符匹配。
  • \t :匹配单个 tab 符。
  • \n :匹配单个换行符。
  • \r :匹配单个回车符。
  • ^ 和 $ :分别匹配字符串的开头或结尾。
  • [..] :匹配方括号中..表达的字符。
  • [^..] :匹配方括号中..表达以外的任何字符。
  • {m,n} :匹配前一个字符的出现次数在 m 至 n 次之间。
  • a|b :匹配 a 或 b。
  • :匹配前一个字符出现次数 0 或 1。
  • +:模式前一个字符出现 1 次或多次。
  • *:模式前一个字符出现 0 次或多次。
  • \ :转义字符,通常用于将一些被占用成为正则表达的符号还原为原来的意思,比如 \+ 表示加号。
  • ():被括起来的表达式部分将作为分组,并返回相匹配的文本。

如果是第一次接触正则表达式的朋友,可能会觉得这些语法有些难记有些抽像,并且难以理解,这是正常现象,不必担心。事实上,我们通过一些代码示例及练习,便可以快速地在实践中学会灵活使用正则表达式。而在 Python 中,通过内嵌集成 re 模块,我们可以直接调用从而快速实现正则匹配,re 中常用的功能有:

  • re.match():从字符串中的首字符开始匹配相应的模式串。
  • re.search():从字符串中的任意位置都可以匹配相应的模式串,只要找到第一个匹配即返回,如果字符串没有匹配,则返回 None。
  • re.findall():从字符串中的任意位置都可以匹配相应的模式串,找到所有匹配情况后返回,如果字符串没有匹配,则返回 None。
  • re.sub():从字符串中的任意位置都可以匹配相应的模式串,找到所有匹配情况后替换成希望的表达形式,返回替换后的字符串。

注:这里的“模式串”,英文称为 pattern,指的便是使用正则语法所构成的一种表达式。 

接下来分别就 re.match()re.search()re.findall() 做一些简单的代码演示,同学们可以观察结果,深入理解这三者的区别。

 教学代码:

import re
# r'自然语言'指模式串,'自然语言处理'指要被匹配的字符串
# 注:模式串前加 r 是为了防止字符转义
result = re.match(r'自然语言', '自然语言处理')
print(result)  # 匹配成功返回一个匹配的对象,否则返回 None

基于不同函数获取结果的不同部分:

print('Matching string :', result.group())  # 获取被匹配到的部分
print('Starting position of the match :', result.start())  # 获取被匹配到的部分初始位置
print('Ending position of the match :', result.end())  # 获取被匹配到的部分结束位置

result = re.match(r'语言', '自然语言处理')  # 注意 match 需要从首字符开始匹配
print(result)  # 匹配成功返回一个匹配的对象,否则返回 None
# 搜寻字符串中任意位置都可能匹配的模式串,找到首个即返回
result = re.search(r'语言', '自然语言处理自然语言')
print(result)  # 匹配成功返回一个匹配的对象,否则返回 None
print('Matching string :', result.group())  # 获取被匹配到的部分

# 搜寻字符串中任意位置都可能匹配的模式串,遍历匹配,可以获取字符串中所有匹配的字符串,
result = re.findall(r'语言', '自然语言处理自然语言')
print(result)  # 返回一个列表

在这里总结一下 re.match() , re.search() 以及 re.findall() 之间的区别:

  • re.match() 只从字符串的开始位置进行匹配,如果字符串不符合正则表达式,则匹配失败,函数返回 None;
  • re.search() 匹配整个字符串,从任意位置都可以开始匹配,直到找到一个匹配即返回;
  • re.findall() 则会找到所有匹配结果并返回。
     

如果想替换字符串中的符合某些模式的地方,可以使用 re.sub()

# r'自然语言'指模式串,'language'指替换内容,'自然语言处理'指要被匹配的字符串
result = re.sub(r'语言', 'language', '自然语言处理语言')
print(result)

 通过以上简单的例子,我们熟悉了 re 模块中一些常用函数的功能,接下来增加难度,尝试用更复杂的正则表达式语法规则来解决一些实际问题。

题目:抽取一段英文中的首个单词。

# 使用了模式串 r'^\w+',这是因为 ^ 表示字符串的开始部分,而 \w+ 可以表示多个连续的字母。
result = re.findall(r'^\w+', 'Whatever is worth doing is worth doing well.')
print(result)

题目:返回邮箱地址中的域名。

# r'@\w+\.(\w+)' 中最后的 \w+ 左右加了括号,因此只会返回括号中匹配的部分
# . 能够匹配除换行符 \n 以外的任意单个字符,这里需要匹配原本的 . 所以加上转义字符变为 \.
result = re.findall(
    r'@\w+\.(\w+)', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')
print(result)

题目:返回字符串中固定格式的日期,如 11-09-2020。

# \d{2}表示两个数字,同理得表达式为 r'\d{2}-\d{2}-\d{4}'
result = re.findall(
    r'\d{2}-\d{2}-\d{4}', 'Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009')
print(result)

题目:只保留字符串中的中文字符。

# 中文的 Unicode 范围为 \u4e00-\u9fa5,前面加 ^ 表示非汉字
# 注意 ^ 放在 [] 中才表示“非”的意义,而放在外面则表示“初始位置”的意义
result = re.sub(r'[^\u4e00-\u9fa5]', '', 'language 自然!!·~语言##处理;’;')
print(result)

题目:验证是否为身份证号码。
注:身份证号可能为 15 或 18 位,15 位全为数字,18 位中前 17 位为数字,最后一位为 X 或者 x。

# r'(^\d{15}$)|(^\d{18}$)|(^\d{17}(X|x)$)' 中三个大括号中的表达式分别对应以上三种情况
# 一头一尾的 ^ 以及 $ 表明匹配的范围是字符串的起止范围
result = re.match(
    r'(^\d{15}$)|(^\d{18}$)|(^\d{17}(X|x)$)', '94023856739300998X')
print(result)

经过了以上例子的学习,同学们是不是对正则表达式多了一些理解了呢。大家在学习正则表达式的时候,一定要多加练习,多实践,多跑跑代码,效果比单纯地记忆各种正则表达式语法好多了。

 

 

 


http://www.kler.cn/a/509380.html

相关文章:

  • 挖掘机检测数据集,准确识别率91.0%,4327张原始图片,支持YOLO,COCO JSON,PASICAL VOC XML等多种格式标注
  • 记录 idea 启动 tomcat 控制台输出乱码问题解决
  • JEL分类号
  • 【王树森搜索引擎技术】概要01:搜索引擎的基本概念
  • 个人vue3-学习笔记
  • R语言绘图
  • 【postgres】sqlite格式如何导入postgres数据库
  • TY1801 反激变换器PWM GaN功率开关
  • uniapp --- 配置文件
  • 鸿蒙UI开发——键盘弹出避让模式设置
  • [javaWeb]初识Web
  • 贪心算法(题1)区间选点
  • 基于海思soc的智能产品开发(高、中、低soc、以及和fpga的搭配)
  • 云消息队列 Kafka 版 V3 系列荣获信通院“云原生技术创新标杆案例”
  • 如何在MongoDB中监视查询慢的语句
  • 深入剖析Java线程安全的集合类:原理、特点与应用
  • 系统编程(进程通信--消息队列)
  • mfc操作json示例
  • Vulnhub-Tr0ll靶机笔记
  • MySql操作指南5--事务与并发控制
  • 2.1 使用kubectl部署一个简单的nginx-pod
  • 内存与缓存:保姆级图文详解
  • 上位机工作感想-2024年工作总结和来年计划
  • PyCharm中解决依赖冲突
  • ESP8266-01S、手机、STM32连接
  • [Computer Vision]实验一:图像的基本操作