Py学习  »  Python

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

checkmate • 7 年前 • 2371 次点击  

我想得到所有匹配的数字(仅数字示例'0012--22')或包含一些文本的数字(示例'rf332'),这些文本与提供的字符串列表(代码中的“我的列表”)匹配。带有数字的文本将以一个或两个空格分隔的格式出现。提供样本输入文件供参考。

这是输入文件:

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

等等。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40065
文章 [ 2 ]  |  最新文章 7 年前
FailSafe
Reply   •   1 楼
FailSafe    7 年前

确实需要有一些东西可以让不到50+代表点的用户发表评论,因为这个线程是我非常好奇的,我想放弃,但不想给出一个完整的答案,因为我给出的答案涉及有限的情况,而不是存在。

@威克托斯特里比奥

您的解决方案错过了基于您的演示的输出的“ref.”部分。看来他想跳过“电车”

@将死

在您想要的输出中,您需要编辑它,因为“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}权宜之计“
  • 首先,需要对“11”进行编辑,以考虑可能存在的其他长度的信息,因此它不灵活
  • 其次,如果它后面跟“reference”相反,那么第三个“ref”将被错误地捕获
Wiktor Stribiżew
Reply   •   2 楼
Wiktor Stribiżew    7 年前

你可以用

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

见 regex demo .

图案细节

  • (?<!\w) -左字边界(明确, \b 意思是上下文相关的,如果下一个字符是非单词字符,它需要在左边有一个单词字符,这不是用户通常期望的)
  • (your|escaped|keywords|here) -捕获组1:您的关键字列表,可以使用 '|'.join(map(re.escape,my_list)) (音符 re.escape 必须转义特殊的regex元字符,如 . , + , ( , [ 等)
  • \W* -0+非字字符(除字母、数字或 _ )
  • ([A-Z]*\d+(?:-+[A-Z]*\d+)*) -捕捉组2:
    • [A-Z]* -零个或多个大写ASCII字母
    • \d+ -一个或多个数字
    • (?:-+[A-Z]*\d+)* -0次或多次重复
      • -+ -一个或多个连字符
      • [A-Z]*\d+ -零个或多个大写ASCII字母,1个或多个数字

见 Python demo :

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')]