您可以模拟 Python re 不支持的 atomic group。
为此,您可以使用
total\s+amount\s*(?::\s*)?(?=(\d[\d,.]*))\1(?!\s*kgs)
见regex demo
详情
-
total\s+amount - total,1+ 个空格,amount
-
\s* - 0+ 个空格
-
(?::\s*)? - 一个可选组,匹配 1 次或 0 次出现的 : 和 0+ 个空格
-
(?=(\d[\d,.]*)) - 一个正向前瞻,匹配并捕获到第 1 组一个数字,然后是 0 个或多个数字、点或逗号
-
\1 - 捕获组 #1 的值(不允许回溯到反向引用,因此后续的前瞻只会触发一次,如果失败,整个匹配将失败)
-
(?!\s*kgs) - 如果有 0+ 个空格,然后在当前位置右侧紧邻 kgs,则匹配失败。
在 Python 中,使用
pattern = r'total\s+amount\s*(?::\s*)?(?=(\d[\d,.]*))\1(?!\s*kgs)'
注意:PyPi regex module 支持原子组和所有格量词,您可以只使用
total\s+amount\s*(?::\s*)?\d[\d,.]*+(?!\s*kgs)
# ^^
查看regex demo(设置了 PHP 选项,因为这将在 Python 代码中具有相同的行为)。
*+0 或更多 量词是主动的,一旦数字、逗号和点匹配,该模式将永远不会重试,并且只会执行一次否定的前瞻检查。 p>
Python test online:
import regex, re
texts = ['task1. total amount 5,887.99 kgs','task2. total amount 5,887.99kgs','task3. total amount 5,887.99 usd','task4. total amount 5,887.99usd']
re_rx = r'total\s+amount\s*(?::\s*)?(?=(\d[\d,.]*))\1(?!\s*kgs)'
regex_rx = r'total\s+amount\s*(?::\s*)?\d[\d,.]*+(?!\s*kgs)'
for s in texts:
m_rx = re.search(re_rx, s)
if m_rx:
print("'", m_rx.group(), "' matched in '", s,"' with re pattern", sep="")
m_regex = regex.search(regex_rx, s)
if m_regex:
print("'", m_regex.group(), "' matched in '", s,"' with regex pattern", sep="")
输出:
'total amount 5,887.99' matched in 'task3. total amount 5,887.99 usd' with re pattern
'total amount 5,887.99' matched in 'task3. total amount 5,887.99 usd' with regex pattern
'total amount 5,887.99' matched in 'task4. total amount 5,887.99usd' with re pattern
'total amount 5,887.99' matched in 'task4. total amount 5,887.99usd' with regex pattern