如何在Python中使用非密码相关的正则表达式匹配3组中的2组?

时间:2016-04-14 14:22:11

标签: python regex

我看了this answerthis answer以试图弄清楚我的问题,但我不确定它们是否可以直接适用,因为a)我不喜欢&# 39; t必须始终满足条件,并且b)文档非常混乱,允许三者中的任何一个匹配将导致大量的误报。

所以,话虽如此,这是我的问题。我想要匹配的文本行看起来像这样:
x = "10/04 Some brief description blah blah blah 45.00"

所有东西之间的间距都很混乱。然后,我有一些我希望匹配的文本行,如下所示:
y = "VJ../VI Another stupid brief description 1000.00"
z = "11/13 This is another description LO05.13"

我目前使用的正则表达式是:
regex = r"^(\d\d\s?[1/]\s?\d\d\s?[1/]\d\d)\s+(\S+(?:\s+\S+)*?)\s+(-?\s?[\d,]+\.\d\d)"

问题在于y regex没有匹配,因为字符串开头没有日期; OCR过程搞砸了。但是,我们仍然知道它是一个有效的行,因为它有描述和数量。 regex赢得了z的匹配,因为金额不是一堆数字,但我们知道它是一个交易,因为它有一个日期和描述。

我考虑过改变正则表达式如下:
regex = r"^(\d\d\s?[1/]\s?\d\d\s?[1/]\d\d\s+)?(\S+(?:\s+\S+)*?)\s+(-?\s?[\d,]+\.\d\d)?"

但是我担心这会匹配文档中的所有内容(即"取款和借记")。由于文本行的两个可选部分位于文本中更一致的部分的两端,因此我不确定如何在我链接的问题的解决方案中实现|。 / p>

我最好选择制作两个不同的正则表达式,与|相关联,就像这样吗? regex = r"^(\d\d\s?[1/]\s?\d\d\s?[1/]\d\d\s+)?(\S+(?:\s+\S+)*?)\s+(-?\s?[\d,]+\.\d\d)|^(\d\d\s?[1/]\s?\d\d\s?[1/]\d\d)\s+(\S+(?:\s+\S+)*?)\s+(-?\s?[\d,]+\.\d\d)?"

任何帮助将不胜感激。感谢

2 个答案:

答案 0 :(得分:1)

使用OCR输入,很难找到100%安全的方法。如果没有实际的输出,我们只能就如何处理每个具体案例提出一个大致的想法。

在这里,我建议

r'^(\w+[^\s/]*/\w{2}\b.*?)\s*(\d+\.\d{2})$'

请参阅regex demo

模式相当普遍:

  • ^ - 字符串/行
  • 的开头
  • (\w+[^\s/]*/\w{2}\b.*?) - 1个以上的字母数字符号或下划线(可能\w+可以替换为\w),后跟0 +非空格和非/字符使用/,然后使用恰好2" word"字符后跟一个单词边界\b,然后尽可能少地使用0 +字符而不是换行符
  • \s* - 0+空白
  • (\d+\.\d{2}) - 最后一个浮点数,整数部分可以有1位数,小数部分可以有2位数
  • $ - 字符串/行的结尾

使用limiting quantifiercharacter classes,您可以进一步微调模式。

答案 1 :(得分:0)

我认为标题中提出的解决方案是将您正在寻找的内容分解为一系列更集中的正则表达式,然后看看您遇到了多少个正则表达式。

例如我做了:

regex = r"\d\d/\d\d"
regex_2 = r".*\s[\d]+\.\d\d"

然后做了:

for i in [x,y,z]:
  tests = [re.match(regex, i), re.match(regex_2, i)]
  print sum([1 if j else 0 for j in tests])

得到了:

2
1
1

在为描述编写第三个正则表达式之前,我需要更多信息,但我认为这是前进的方向。