按字面和被动匹配换行符的正则表达式
Regex that matches newlines literally and passively
我必须构建一个匹配客户端代码的正则表达式,如下所示:
- XXX/X{3,6}
- XXX.X{3,6}
- XXX.X{3,6}/XXX
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
. ,则不会触发右空白边界
我必须构建一个匹配客户端代码的正则表达式,如下所示:
- XXX/X{3,6}
- XXX.X{3,6}
- XXX.X{3,6}/XXX
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.
你们知道如何解决这个问题吗?感谢所有输入。谢谢!
您似乎想从空白边界中减去 \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
字符组合 中的 \d{3}
- 三位数[./]
- 一个.
或/
\d{3,6}
- 三到六位数(?:/\d{3})?
-/
和三个数字 的可选序列
(?![^\s\n])
- 一个否定的前瞻,除了当前位置右侧的空格和 LF 之外不需要任何字符。(?!(?!\n)\S)
- 如果非空白是\
字符后跟n
. ,则不会触发右空白边界
n
,则不会触发左空白边界