【问题标题】:Regex match specific word in string but exclude indexed versions正则表达式匹配字符串中的特定单词但排除索引版本
【发布时间】:2018-05-14 03:44:40
【问题描述】:

我敢肯定,如果存在解决方案,那么它就在某个地方,但我找不到它。我关注Python regex to match a specific word 并在第一方面取得了成功,但现在在第二方面苦苦挣扎。

我继承了一种可怕的文件格式,其中每个测试结果都在自己的一行中。每条记录限制为 12 个字符,因此一些结果被分成多组行,例如 SITE、SITE1 和 SITE2。我正在尝试将文件解析为字典,以便可以对其进行更多分析并最终生成格式化报告。

上面的链接/下面的代码允许我匹配每个站点并将它们连接在一起,但它给我正确匹配 INS、INS 1 和 INS 2 的问题。是的,这个空间是故意的——这是我必须处理的。 INS 是测试结果,INS 1 是通过的测试限制。

是否有匹配的正则表达式

SITE > SITE 为真,但 SITE > SITE1 为假

INS > INS 为真但 INS 到 INS 1 为假?

这里是python代码。

import re    
lines = ['SITE start', 'SITE1 more', 'SITE2 end','INS value1', 'INS 1 value2']
headings = ['SITE','SITE1',"SITE2", "INS", "INS 1"]
for line in lines:
    for heading in headings:
        headregex = r"\b" + heading + r"\b"
        match = re.search(headregex,heading)
        if match:
            print "Found " + heading + " " + line
        else:
            print "Not Found " + heading + " " + line

这里有一些虚拟数据:

TEST MODE 131 AUTO SITE startaddy SITE1 middle addy SITE2 end addy
USER DB VISUAL CHECK P BOND RANGE 25A EARTH 0.09 OHM P LIMIT 0.10 OHM INS 500 V INS 1 >299 MEG P ... TEST MODE 231 AUTO SITE startaddy SITE1 middle addy SITE2 end addy USER DB VISUAL CHECK P INS 500 V INS 2 >299 MEG P ...

对不起,可怕的格式 - 它是从我正在处理的内容中复制和粘贴的!

【问题讨论】:

  • 你为什么同时使用re.escape\bs? headings 可以包含什么?他们可以以非单词字符开头/结尾吗?
  • re.escape 和 \b - 缺乏经验!从我得到的 24 条左右的样本记录来看,它们看起来都以字母开头,没有空格等,但许多其他空白内容出现在该行的后面。
  • 你能举个实际的例子吗?根据您提供的描述,我不确定需要满足哪些条件。
  • Arne,如果您可以运行代码,那么 Site 应该与 Site 匹配,而不是 Site1 或 Site2。 Ins 应与 Ins 匹配,但与 Ins 1 不匹配。
  • 您只能通过在INS 之后添加(?! 1\b) 前瞻来排除该匹配项,请参阅ideone.com/90TJE3。您似乎想检查是否所有标题都匹配,而不仅仅是找到的第一个,这使得它相当困难。

标签: python regex


【解决方案1】:

只是为了给出一个可能解决问题的答案,同时避免一些乏味,这就是你想要实现的目标吗?

import re

lines = ['SITE start', 'SITE1 more', 'SITE2 end','INS value1', 'INS 1 value2']
headings = ['SITE','SITE1',"SITE2", "INS", "INS 1"]

headings_re = re.compile(r"(SITE\d? )?(INS( \d)?)? (.*)") 
# build by hand, only works if SITE and INS are the literal identifiers 

site = []
ins = []

for line in lines:
  match = headings_re.match(line)
  if match:
    if match.group(1):
      site.append(match.group(4))
    elif match.group(2):
      ins.append(match.group(4))
    else:
      print("something weird happened")
      print(match.group(0))
  else:
    print("something weird happened")
    print(line)

print("SITE: {}".format(" ".join(site)))
>> SITE: start more end
print("INS: {}".format(" ".join(ins)))
>> INS:  value1  value2

【讨论】:

  • 没有。这对我没有帮助 - 对不起。我将编辑原始问题以显示一些虚拟数据。
【解决方案2】:

问题是 INS 模式在 INS 中找到部分匹配 INS 1INS 2 等。

在提取替代项的情况下,习惯上使用从最长值开始的替代项(如INS \d+|INS),但在这种情况下,您希望获取所有正则表达式匹配项的列表,仅排除一些重叠的标题匹配项。

为了实现这一点,有一种方法可以通过将所有标题项视为正则表达式来排除匹配,并将INS 模式定义为INS(?! \d) 以确保INS 不匹配,如果它后跟一个空格和一个数字。

Python demo

import re    
lines = ['SITE start', 'SITE1 more', 'SITE2 end','INS value1', 'INS 1 value2']
headings = ['SITE','SITE1',"SITE2", r"INS(?! \d)", "INS 1"]
headings=sorted(headings, key=lambda x: len(x), reverse=True)
for line in lines:
    print("----")
    for heading in headings:
        headregex = r"\b{}\b".format(heading)
        match = re.search(headregex,heading)
        if match:
            print "Found " + heading + " " + line
        else:
            print "Not Found " + heading + " " + line

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2011-01-05
    • 2017-04-28
    • 1970-01-01
    相关资源
    最近更新 更多