【问题标题】:Regex: Find word but not allow repetition正则表达式:查找单词但不允许重复
【发布时间】:2018-04-02 22:36:20
【问题描述】:

我有以下测试,我想提取 HAB: 之后的所有代码,它们前面必须有 REST,但中间可以有其他词:

REST gfdjj REST HAB:75RF-3729-70D-01 CLUE HAB:234-543 REST tt HAB:75RF-3729-70D-02 CLUE ytr HAB:34829-5467 REST HAB:75RF-3729-70D-03 REST REST REST HAB:54783-04 REST HA:8374​​83 REST dfhjdf REST 347845-34 REST rehs HAB:45923 REST HAB:REST sdfdgdsd HAB:456734

https://regex101.com/r/4inYr4/3

我试过(REST.*?) *(HAB:) (.*?)( |$),但它也返回了许多冗余的REST

(REST) *(HAB:) (.*?)( |$) 但它不返回第二个代码,

(REST(?!.*REST).*?) *(HAB:) (.*?)( |$),但它只返回最后一个。

我需要某种条件正则表达式,它只允许 RESTHAB: 之间出现除 REST 之外的其他词,这是我所期望的最后一个要做?

编辑:

我要提取:

  1. REST 75RF-3729-70D-01

  2. REST 75RF-3729-70D-02

  3. REST 75RF-3729-70D-03

  4. REST 54783-04

  5. REST 45923

编辑 2:

我需要 REST 部分,我更新了问题并添加了一些 CLUE 以强调我需要 REST

我使用 Python 2.7

编辑 3:

我还需要在以下位置找到 REST 456734:

REST HAB:REST sdfdgdsd HAB:456734

【问题讨论】:

  • 你想从你的样本中匹配什么?
  • 在您的 regex101 测试中,您的测试字符串不包括代码上的 -01 到 -04 后缀。当我穿上这些并使用您的第二个正则表达式时,它会返回所有 3 个代码 75RF-3729-70D-01、75RF-3729-70D-03 和 54783-04
  • 您需要REST 部分吗?另外,您使用的是什么工具/语言?
  • 但是45923后面没有HAB。

标签: python regex python-2.7


【解决方案1】:

您要求匹配从RESTHAB: 不包括REST 的文本实际上没有帮助,它不会对匹配产生太大影响,但是HAB: 之后的文本不能是REST,因为它会阻止有效匹配。

你可以使用

(REST).*?HAB:\s*(?!REST(?!\S))(\S+)

regex demo

详情

  • (REST) - 第 1 组:REST 子字符串
  • .*? - 除换行符以外的任何 0+ 个字符,尽可能少
  • HAB: - HAB: 文字子字符串
  • \s* - 0+ 个空格
  • (?!REST(?!\S)) - 如果紧挨当前位置的右侧有 REST 后跟空格或字符串结尾,则会导致匹配失败
  • (\S+) - 第 2 组:任何 1+ 个非空白字符。

Python code demo:

import re
rx = r"(REST).*?HAB:\s*(?!REST(?!\S))(\S+)"
s = """REST gfdjj REST HAB: 75RF-3729-70D-01 CLUE HAB: 234-543 REST tt HAB: 75RF-3729-70D-02 CLUE ytr HAB: 34829-5467 REST HAB: 75RF-3729-70D-03 REST REST REST HAB: 54783-04 REST HA: 837483 REST dfhjdf REST 347845-34 REST rehs HAB: 45923\nREST HAB: REST sdfdgdsd HAB: 456734"""
res = ["{} {}".format(x.group(1),x.group(2)) for x in re.finditer(rx, s)]
print(res)
# => ['REST 75RF-3729-70D-01', 'REST 75RF-3729-70D-02', 'REST 75RF-3729-70D-03', 
#    'REST 54783-04', 'REST 45923', 'REST 456734']

【讨论】:

  • 他使用python 2.7,我不认为你的代码在那里工作。但在python 3 中它工作正常。
  • @ShashankSingh The link 证明了这一点。
  • 糟糕,我在python 2.6 上试过了,对不起。它确实有效。
  • 是否可以强制完全不捕获 REST,而不仅仅是在右侧?
【解决方案2】:

你想要这样的输出吗?

REST 75RF-3729-70D-01
REST 75RF-3729-70D-02
REST 75RF-3729-70D-03
REST 54783-04
REST 45923
REST 456734
REST 456734

你可以试试这个模式。

.*?(REST\s)(?:(?:(?!REST|HAB).)*HAB\:\s*)(\b(?:(?!REST)[-\w])+\b)

Demo

您要提取的内容在捕获组 1、2 中成对捕获

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    相关资源
    最近更新 更多