为了账号安全,请及时绑定邮箱和手机立即绑定

在 Python 中匹配字符串的特定模式之后获取数字

在 Python 中匹配字符串的特定模式之后获取数字

慕婉清6462132 2021-11-30 16:35:08
我想获取所有匹配的数字(仅数字示例 '0012--22')或包含与其对应的一些文本(示例 'RF332')的数字,这些文本与提供的字符串列表匹配(代码中的“my_list”) . 带有数字的文本出现的格式就像用一两个空格分隔。提供示例输入文件以供参考。这是输入文件:$cat input_filesome text before Expedien: 1-21-212-16-26 some random textReference RE9833 of all sentences.abc123456something blah blah Ref.: tramite  1234567Ref.:some junk Expedien N° 18-00777 # some new contentsome text Expedien N°18-0022995 # some garbled content到目前为止的脚本附在下面:它目前只识别一个元素,它是 {'tramite': '1234567'}import reimport globimport osmy_list = ['Ref.:', 'Reference', 'tramite', 'Expediente', 'Expediente No', 'Expedien N°', 'Exp.No', 'Expedien']#open the file as inputwith open('garb.txt','r') as infile:  res = dict()  for line in infile:      elems = re.split('(?::)?\s+', line)    #print(elems)    if len(elems) >= 2 :      contains = False      tmp = ''      for elem in elems:          if contains:          res.update({tmp : elem})          print(res)          contains = False          break        if elem in my_list:          contains = True          tmp = elem  #print(res)这是预期的输出:示例输出:{'Expedien N°': '18-0022995'}{'Expedien N°': '18-0022995'}{'Expedien': '1-21-212-16-26'}{'Reference' : 'RE9833'}等等等等
查看完整描述

2 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

您可以使用

(?<!\w)(your|escaped|keywords|here)\W*([A-Z]*\d+(?:-+[A-Z]*\d+)*)

请参阅正则表达式演示

图案详情

  • (?<!\w)- 左字边界(明确,\b含义取决于上下文,如果下一个字符是非字字符,则左侧需要一个字字符,这不是用户通常期望的)

  • (your|escaped|keywords|here)-捕获组1:您的关键字列表,可以很容易地使用内置'|'.join(map(re.escape,my_list))(注意re.escape是必要的转义特殊的正则表达式的元字符像.+([,等)

  • \W*- 0+ 个非单词字符(字母、数字或 以外的字符_

  • ([A-Z]*\d+(?:-+[A-Z]*\d+)*) - 捕获组 2:

    • -+ - 一个或多个连字符

    • [A-Z]*\d+ - 零个或多个大写 ASCII 字母,1 个或多个数字

    • [A-Z]* - 零个或多个大写 ASCII 字母

    • \d+ - 1 位或更多位

    • (?:-+[A-Z]*\d+)* - 0 次或多次重复

请参阅Python 演示

import re

s="""your_text_here"""

my_list = ['Ref.:', 'Reference', 'tramite', 'Expediente', 'Expediente No', 'Expedien N°', 'Exp.No', 'Expedien']

rx = r'(?<!\w)({})\W*([A-Z]*\d+(?:-+[A-Z]*\d+)*)'.format('|'.join(map(re.escape,my_list)))

print(re.findall(rx, s))

输出:


[('Expedien', '1-21-212-16-26'), ('Reference', 'RE9833'), ('tramite', '1234567'), ('Expedien N°', '18-00777'), ('Expedien N°', '18-0022995')]



查看完整回答
反对 回复 2021-11-30
?
慕沐林林

TA贡献2016条经验 获得超9个赞

确实需要有一些东西允许少于 50 多个代表点的用户发表评论,因为这个线程是我真的很好奇并且想要分叉的线程,但不想给出一个完整的答案上,因为我给出的答案涉及有限的情况并且不灵活。


@Wiktor Stribiżew


您的解决方案错过了“参考”。基于您的演示的输出部分。看起来他想跳过“tramite”


@checkmate


在您想要的输出中,您需要对其进行编辑,因为“UV1234”不会出现在您发布的字符串中的任何位置


.


无论如何,我找到了一个解决方案,但我真的希望有人可以改进这一点。


>>> import re


>>> string = '''some text before Expedien: 1-21-212-16-26 some random text

Reference RE9833 of all sentences.

abc

123

456

something blah blah Ref.: 

tramite  1234567

Ref.:

some junk Expedien N° 18-00777 # some new content

some text Expedien N°18-0022995 # some garbled content'''


>>> re.findall('(?:(Expedien[\s]+N\S|Ref\.(?!:[\S\s]{,11}Expedien)|Reference|Expedien))[\S\s]*?([A-Z\-]*(?:[\d]+)[\S]*)', string)


[('Expedien', '1-21-212-16-26'), ('Reference', 'RE9833'), ('Ref.', '1234567'), ('Expedien N\xb0', '18-00777'), ('Expedien N\xb0', '18-0022995')]

缺陷:


为了正确捕获它部分依赖于“Ref.(?!:[\S\s]{,11}Expedien)”

首先,需要编辑“11”以考虑可能存在的其他长度的信息,因此它不灵活

其次,如果后面是“参考”而不是第三个“参考”。将被错误地捕获


查看完整回答
反对 回复 2021-11-30
  • 2 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信