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

我想获取所有匹配的数字(仅数字示例 '0012--22')或包含与其对应的一些文本(示例 'RF332')的数字,这些文本与提供的字符串列表匹配(代码中的“my_list”) . 带有数字的文本出现的格式就像用一两个空格分隔。提供示例输入文件以供参考。


这是输入文件:


$cat input_file

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

到目前为止的脚本附在下面:它目前只识别一个元素,它是 {'tramite': '1234567'}


import re

import glob

import os


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


#open the file as input

with 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'}

等等等等


慕婉清6462132
浏览 193回答 2
2回答

牧羊人nacy

您可以使用(?<!\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+)*)&nbsp;- 捕获组 2:-+&nbsp;- 一个或多个连字符[A-Z]*\d+&nbsp;- 零个或多个大写 ASCII 字母,1 个或多个数字[A-Z]*&nbsp;- 零个或多个大写 ASCII 字母\d+&nbsp;- 1 位或更多位(?:-+[A-Z]*\d+)*&nbsp;- 0 次或多次重复请参阅Python 演示:import res="""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')]

慕沐林林

确实需要有一些东西允许少于 50 多个代表点的用户发表评论,因为这个线程是我真的很好奇并且想要分叉的线程,但不想给出一个完整的答案上,因为我给出的答案涉及有限的情况并且不灵活。@Wiktor Stribiżew您的解决方案错过了“参考”。基于您的演示的输出部分。看起来他想跳过“tramite”@checkmate在您想要的输出中,您需要对其进行编辑,因为“UV1234”不会出现在您发布的字符串中的任何位置.无论如何,我找到了一个解决方案,但我真的希望有人可以改进这一点。>>> import re>>> string = '''some text before Expedien: 1-21-212-16-26 some random textReference RE9833 of all sentences.abc123456something blah blah Ref.:&nbsp;tramite&nbsp; 1234567Ref.:some junk Expedien N° 18-00777 # some new contentsome 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”以考虑可能存在的其他长度的信息,因此它不灵活其次,如果后面是“参考”而不是第三个“参考”。将被错误地捕获
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python