【问题标题】:Python Regex[Forking] - Capture Groups Based on Terms but Skipping if another Term in the set is encounteredPython Regex[Forking] - 根据术语捕获组,但如果遇到集合中的另一个术语则跳过
【发布时间】:2019-03-11 19:58:27
【问题描述】:

首先,我将@checkmate 提出这个问题,因为发布的解决方案不能准确地满足他在“预期输出”中发布的内容。我不确定他是否没有注意或只是发布不正确,但准确地解决这个问题确实可以帮助“我”解决我的个人项目: Get number present after a particular pattern of a matching string in Python

在他的预期输出中,他发布了:

这是预期的输出:

样本输出:

{'Ref.': 'UV1234'}
{'Expedien N°': '18-0022995'}
{'Expedien N°': '18-0022995'}
{'Expedien': '1-21-212-16-26'}
{'Reference' : 'RE9833'}

请注意,"tramite" 在他的“预期输出”中被明确忽略。还要注意,他在"{'Ref.': 'UV1234'}" 行错误地发布了他的预期输出,因为'UV1234' 从未出现在字符串中。我认为他的意思是"{'Ref.': '1234567'}"。是的,我试过和他们俩聊天,但没有成功。

.

作为回应,我想出了一个超具体的解决方案,它跳过了"tramite",但只要有轻微的差异,正则表达式就会被破坏。此外,因为带有"Ref.:" 的行存在并且随后是"Expedien N° [Numbers]" 对正则表达式的编辑yield "Ref." 被捕获,同时"[Numbers]""Expedien N°" 被忽略,而不是"Expedien N° [Numbers]"(示例这个有缺陷的变体如下)。 我更喜欢使用"re.findall",但我很清楚它不会递归地循环遍历字符串。如果我只能通过"re.search" 实现以下操作,我仍然需要弄清楚如何用它来解决它。

Get number present after a particular pattern of a matching string in Python

>>> 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”以说明捕获组之间可能存在的其他信息长度,我无法弄清楚,所以现在它不灵活

-其次,如果在字符串中需要捕获的内容后面是“参考”或我的另一个术语列表,而不是“Expedien”(再次,它太具体),那么第三个“参考。”将被错误捕获

.

.

.

在这个轻微的变体中,我没有指定 11 的范围并消除 "Ref." 的后视,"Ref." 与数字一起被捕获,"Expedien N°" 应该被捕获而不是 "Ref." , 被忽略

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

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

.

.

.

所以,我想知道:

如果所需查询发生在我拥有的列表中的一个术语与该列表中存在的另一个术语之间,如何使正则表达式不捕获?

.

.

所需的输出如下,但我想知道如何更可靠地获得它,因为我上面的内容非常具体:

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

【问题讨论】:

  • 您的输入数据与其他问题中发布的数据相同吗?
  • 确实如此。哥们你太棒了!!!

标签: python regex skip


【解决方案1】:

有点长,但是这个正则表达式应该对你有用,并且具有负面的前瞻性:

(Ref\.:|Reference|Expediente|Expediente No|Expedien N°|Exp\.No|Expedien)\s*(?:(?!Ref\.:|Reference|Expediente|Expediente No|Expedien N°|Exp\.No|Expedien).)*?([A-Z]*\d+(?:-[A-Z]*\d+)*)

RegEx Demo

(?!...) 是负前瞻,以确保我们不匹配重叠标签。

【讨论】:

  • 非常感谢!!!你真的是个天才。非常感谢您的回复!!!
  • 我会看看我是否可以在反向引用中工作,但这太棒了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多