按字面和被动匹配换行符的正则表达式

Regex that matches newlines literally and passively

我必须构建一个匹配客户端代码的正则表达式,如下所示:

X 是 0 到 9 之间的数字。

正则表达式需要足够强大,这样我们才不会提取另一个字符串中的代码。使用单词边界是我的第一个想法。 正则表达式如下所示:\b\d{3}[\.\/]\d{3,6}(?:\/\d{3})?\b

单词边界的问题是它也匹配点。因此,像“123/456.12”这样的数字将匹配“123/456”作为客户号码。于是我想到了以下正则表达式:(?<!\S)\d{3}[\.\/]\d{3,6}(?:\/\d{3})?(?!\S)。它使用 lookbehind 和 lookahead 并检查该字符是否为白色 space。这正确匹配了大多数客户端代码。

不过还有最后一题。我们正在使用 Google OCR 文本从中提取代码。这意味着可以在 123/456\n\n123/456\n123/456\n 等文本中找到有效代码。检查前一个和/或下一个字符是否为白色 space 不会不起作用,因为文字“\n”不包含在其中。如果我做类似 (?<!\S|\n) 作为单词边界的事情,它也会出于某种原因包含一个反 and/or 正斜杠。目前我想出了以下正则表达式 (?<![^\r\n\t\f\v n])\d{3}[\.\/]\d{3,6}(?:\/\d{3})?(?![^\r\n\t\f\v \]),但它只检查前一个字符是“n”还是白色 space 以及下一个字符是反斜杠还是白色 space。所以像“lorem3/456”这样的字符串仍然会找到匹配项。我需要一些方法在不破坏 lookahead/lookbehind.

的情况下在白色 space 字符中包含“\n”

你们知道如何解决这个问题吗?感谢所有输入。谢谢!

您似乎想从空白边界中减去 \n。您可以使用

re.findall(r'(?<![^\s\n])\d{3}[./]\d{3,6}(?:/\d{3})?(?![^\s\n])', text)

参见Python demo and this regex demo

如果\n\n字符的组合,你需要确保\S在环视与那些不匹配:

import re
text = r'Codes like 123/456\n \n123/3456 \n123/23456\n etc are correct \n333.3333/333\n'
print( re.findall(r'(?<!\S(?<!\n))\d{3}[./]\d{3,6}(?:/\d{3})?(?!(?!\n)\S)', text) )
# => ['123/456', '123/3456', '123/23456', '333.3333/333']

参见 this Python demo

详情:

  • (?<![^\s\n]) - 一个负向后视,它匹配一个位置,该位置前面没有紧跟一个除空格之外的字符和一个 LF 字符
  • (?<!\S(?<!\n)) - 如果非空白是 \n 字符组合
  • 中的 n,则不会触发左空白边界
  • \d{3} - 三位数
  • [./] - 一个 ./
  • \d{3,6} - 三到六位数
  • (?:/\d{3})? - / 和三个数字
  • 的可选序列
  • (?![^\s\n]) - 一个否定的前瞻,除了当前位置右侧的空格和 LF 之外不需要任何字符。
  • (?!(?!\n)\S) - 如果非空白是 \ 字符后跟 n.
  • ,则不会触发右空白边界