使用正则表达式

时间:2018-10-04 23:58:18

标签: python regex python-3.x

我正在尝试使用Regex将这种 kind 免费文本转换成字典。

  丙胺A(12000 UI / kg),硫胺素D3(1200 UI / kg),烟酸E(70 mg / kg),锌[氧化锌](70 mg / kg),锌[酸式锌,水合物](45 mg / kg),铜[硫酸铜(II),五水合物](10 mg / kg),碘[碘酸钙]钙,无水](2 mg / kg),硒(硒钠)(0.2 mg / kg),cyaobactin12(0.2%)

想法是捕获键和值

  • :胺A
  • :12000 UI / kg

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

我尝试了一些选项来实现此文本转换:

第一种方法:直接使用正则表达式(()\((\d*\.*\s*\d*\s*)(UI\/kg|mg\/kg|%)\)),但我只能正确隔离值而不是键。

第二种方法:

  1. 使用这种正则表达式(\[.*),(.*\]来消除括号内的“ ,该正则表达式无法准确捕获[硫酸盐形式(II)五水合物]或[sous for d'iodate de钙**,**酸酐]
    1. 沿“,”分割,使列表看起来像列表[“ alamine A(12000 UI / kg)”,“ thhiamine D3(1200 UI / kg)” ...] 3。对于列表中的每个元素,请使用更简单的正则表达式作为第一种方法(.*)\((\d*\.*\s*\d*\s*)(UI\/kg|mg\/kg|%)\))

我应该如何进行?

3 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

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

将其分解时,您会看到键和值的每个“部分”必须以字符串的开头或末尾带有非捕获组(?:^|,)的逗号开头。 / p>

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

最后,它将使用您现有的代码(略有修改)捕获您的价值:

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

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

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

See it in action

答案 1 :(得分:1)

你去我朋友那里!我使用正则表达式找到每个结果,然后在最后一个(上拆分它们。它覆盖了字符串中的所有异常!!!

#!/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%

答案 2 :(得分:1)

让我们从更简单的部分开始:值。 这是放在括号中的内容:(?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
)

现在将它们放在一起:(?:(?<=,\s)|^)(?P<key>[^[(]+(?:\[[^]]+\])?)\s(?P<value>\([^)]+\))