regex向前看和向后看

2024-05-16 21:57:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下两种不同的刮取数据:

   txt =  '''Käuferprovision: 3 % zzgl. gesetzl. MwSt.''' # variation 1

    txt = '''Käuferprovision: Die Courtage i.H.v. % 3,57 inkl. MwSt. ist''' # variation 2

我想创建一个正则表达式,以浮点数的形式获取百分比,因此在第一个例子中是3.0,在第二个例子中是3.57

到目前为止,我已经试过了:

m = re.search(r'.{3}.%.{5}',txt)
txt = m.group().split("%")[1:]
txt = ("".join(txt)).replace(",",".")
print(txt)

它适用于变量2,但不适用于变量1


Tags: 数据txt形式例子百分比浮点数dievariation
3条回答

还有一种方法-使用PyPiregex的分支重置:

import regex as re

data = """
Käuferprovision: 3 % zzgl. gesetzl. MwSt.
Käuferprovision: Die Courtage i.H.v. % 3,57 inkl. MwSt. ist
"""
rx = re.compile(r'(?|(?P<value>\d+(?:,\d+)?)\s*%|%\s*(?P<value>\d+(?:,\d+)?))')

for m in rx.finditer(data):
    print(float(m.group('value').replace(',', '.')))

产生

3.0
3.57

a demo on regex101.com


如果你想彻底疯掉,可以使用一个子程序进行分支重置(无可否认,这太过分了):

(?(DEFINE)
    (?<value>\d+(?:,\d+)?)
    (?<before>%\s+)
    (?<after>\s+%)
)

(?|(?P<mwst>(?&value))(?&after)|(?&before)(?P<mwst>(?&value)))

见另一个demo on regex101.com

您可以使用2个捕获组的替代方案,并检查存在哪个组

\b(\d+(?:\,\d+)?)\s*%|%\s*(\d+(?:\,\d+)?)\b

见a regex demo

模式匹配:

  • \b单词边界
  • (\d+(?:\,\d+)?)\s*%捕获组1-将数字与可选的十进制、可选的空白字符和%匹配
  • |
  • %\s*(\d+(?:\,\d+)?)捕获第2组-\b单词边界-与第1组相反
  • \b单词边界

比如说

import re

regex = r"\b(\d+(?:\,\d+)?)\s*%|%\s*(\d+(?:\,\d+)?)\b"
test_str = ("Käuferprovision: 3 % zzgl. gesetzl. MwSt.\n"
            "Käuferprovision: Die Courtage i.H.v. % 3,57 inkl. MwSt. ist")

matches = re.finditer(regex, test_str, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
    if match.group(1):
        print(match.group(1).replace(',', '.'))
    else:
        print(match.group(2).replace(',', '.'))

输出

3
3.57

如果百分号之间的空格是固定的,您还可以使用lookarounds仅获取不带组的匹配

(?<=% )\b\d+(?:,\d+)\b|\b\d+(?:,\d+)?(?= %)

另见regex demo

范例

import re

pattern = r"(?<=% )\b\d+(?:,\d+)\b|\b\d+(?:,\d+)?(?= %)"
test_str = ("Käuferprovision: 3 % zzgl. gesetzl. MwSt.\n"
            "Käuferprovision: Die Courtage i.H.v. % 3,57 inkl. MwSt. ist")

for s in re.findall(pattern, test_str):
    print(s.replace(",", "."))

输出

3
3.57

您可以尝试使用以下代码获取百分比值并将其转换为float

>>> import re
>>> arr = ['Käuferprovision: 3 % zzgl. gesetzl. MwSt.', 'Käuferprovision: Die Courtage i.H.v. % 3,57 inkl. MwSt. ist']
>>> rx = re.compile(r'\d+(?:[.,]\d+)*(?=\s*%)|(?<=%)\s*\d+(?:[.,]\d+)*')
>>> for s in arr:
...     for m in rx.finditer(s): print (float(m.group().replace(',', '.')))
...
3.0
3.57

RegEx Demo

Online Code Demo

相关问题 更多 >