用Regex将自由文本解析成dict

2024-06-13 14:10:27 发布

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

我正试着用Regex把这个自由文本转换成字典。你知道吗

alamine A (12 000 UI/kg), thiamine D3 (1 200 UI/kg), niacine E (70 mg/kg), zinc [sous forme d'oxyde de zinc] (70 mg/kg), zinc [sous forme de chélate de zinc d'acides aminés, hydraté] (45 mg/kg), copper [sous forme de sulfate de cuivre (II), pentahydraté] (10 mg/kg), iode [sous forme d'iodate de calcium, anhydre] (2 mg/kg), sélénium [sous forme de sélénite de sodium] (0.2 mg/kg), cyaobactin12 (0.2%)

我们的想法是抓住关键和价值

  • 按键:alamine A
  • :12000 UI/kg

或者

  • :铜[硫酸铜(II),五水合]
  • :10 mg/kg

我尝试使用以下选项来实现此文本转换:

第一种方法:直接使用regex (()\((\d*\.*\s*\d*\s*)(UI\/kg|mg\/kg|%)\))但是我只能正确地隔离值而不是键。你知道吗

第二种方法:

  1. 去掉括号内的“”,这种正则表达式(\[.*),(.*\]不能准确地捕获[sous forme de sulfate de cuivre(II)pentahydrateé]或[sous forme d'iodate de cacium**,**anhydre]
    1. 沿着“,”使列表看起来像列表[“alamine A(12000 UI/kg)”,“thiamine D3(1200 UI/kg)”…] 三。对于列表中的每个元素,使用更简单的regex作为第一种方法(.*)\((\d*\.*\s*\d*\s*)(UI\/kg|mg\/kg|%)\))

我该怎么办?你知道吗


Tags: 方法文本ui列表deiid3kg
3条回答

给你,我的朋友!我使用正则表达式找到每个结果,然后在最后一个(上拆分它们。它涵盖了字符串中的每个异常!!!你知道吗

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
text = "alamine A (12 000 UI/kg), thiamine D3 (1 200 UI/kg), niacine E (70 mg/kg), zinc [sous forme d'oxyde de zinc] (70 mg/kg), zinc [sous forme de chélate de zinc d'acides aminés, hydraté] (45 mg/kg), copper [sous forme de sulfate de cuivre (II), pentahydraté] (10 mg/kg), iode [sous forme d'iodate de calcium, anhydre] (2 mg/kg), sélénium [sous forme de sélénite de sodium] (0.2 mg/kg), cyaobactin12 (0.2%)"
my_regex = re.compile(r"([^,]*\[[^\]]*\]\s\([^\)]*\)|[^,]*\([^\)]*\))")
matches = re.findall(my_regex, text)
clean_result = []
for str in matches:
    res = str.rsplit('(', 1)
    clean_result.append((res[0].strip(), res[1][:-1]))

for res in clean_result:
    print "key : " + res[0].decode('utf-8')
    print "value : " + res[1].decode('utf-8')
    print

输出

key : alamine A
value : 12 000 UI/kg

key : thiamine D3
value : 1 200 UI/kg

key : niacine E
value : 70 mg/kg

key : zinc [sous forme d'oxyde de zinc]
value : 70 mg/kg

key : zinc [sous forme de chélate de zinc d'acides aminés, hydraté]
value : 45 mg/kg

key : copper [sous forme de sulfate de cuivre (II), pentahydraté]
value : 10 mg/kg

key : iode [sous forme d'iodate de calcium, anhydre]
value : 2 mg/kg

key : sélénium [sous forme de sélénite de sodium]
value : 0.2 mg/kg

key : cyaobactin12
value : 0.2%

您可以尝试以下方法:

(?:^|,)(.*?)(\((?:\d*\.*\s*\d*\s*)(?:UI\/kg|mg\/kg|%)\))

当您将其分解时,您将看到键和值的每个“部分”必须以字符串开头或最后一部分的逗号开头,并带有非捕获组(?:^|,)。你知道吗

然后,它将使用非贪婪量词(.*?)\(捕获到下一个左括号的所有内容。这是你的“钥匙”。你知道吗

最后,它将捕获您的价值与您现有的代码,稍加修改:

(\((?:\d*\.*\s*\d*\s*)(?:UI\/kg|mg\/kg|%)\))

如果要修剪捕获中多余的空格,可以将\s*添加到键组的任一侧:

(?:^|,)\s*(.*?)\s*(\((?:\d*\.*\s*\d*\s*)(?:UI\/kg|mg\/kg|%)\))

See it in action

让我们从更简单的部分开始:价值。 用括号括起来:(?P<value>\([^)]+\))

(?P<value> # Capturing "value" group
  \(       # Matches an opening parentheses
  [^)]+    # Matches one or more non ")" characters
  \)       # Matches a closing parentheses
)

完成了,我们来处理钥匙。
这里的一点是,键可能包含一些用方括号括起来的文本。
然后是任何非([字符,后面可能跟有括号中的任何字符:(?P<key>[^[(]+(?:\[[^]]+\])?)

(?P<key>  # Capturing "key" group
  [^[(]+  # One or more non "(" or "[" characters
  (?:     # Non-capturing group
    \[    # An opening bracket
    [^]]+ # One or more non "]" characters
    \]    # A closing bracket
  )?      # Non-capturing group made optional
)

工作即将完成。
我们将在两个组之间添加一个\s作为分隔符。
最后,让我们来处理序列分隔符:(?:(?<=,\s)|^)

(?:        # Non-capturing group
  (?<=,\s) # Either preceded by a coma and a space
  |^       # Or alternatively beginning the string
)

现在把它们放在一起:^{}

相关问题 更多 >