无法使用包含unicode的字符串获得正确的python正则表达式

时间:2014-12-04 17:32:39

标签: python regex unicode

我有这个字符串:

s = u'vitamin a min. 14,053 iu/kg   vitamin c 13,000iu/kg vitamin d max. 10,000\u03bc/kg copper 1mg/kg vitamin e mon 10.00iu/kg'

我想把它拆开,所以我得到[label, label2, amount, units]

  • label是名称,vitamin c,可以包含unicode字符
  • label2min|max,具体取决于特定字符串。
  • amount是列出的数字量(可以包括逗号或小数)
  • units可以包含unicode字符

你可以看到一些边缘情况已经出现:

  • 某些成分不包含label2 = minmax(请参阅coppervitamin c)。在这种情况下,正则表达式分组可以是None
  • 某些成分label2被误导(请参阅vitamin e使用mon
  • 单位中可能有unicode

理想情况下,我想要一个可以匹配单个成分的正则表达式以及一个杂乱的列表(就像我提供的那样)。

我想出了:

import re
regex = re.compile(ur'([a-z 0-9]+)(min|max|mon)?[. ]+([0-9., ]+)((?=[%])|[a-z/]+|[^\W\d_]+/[^\W\d_]+)', re.UNICODE)


re.findall(regex, s)

# [(u'vitamin a min', u'', u'14,053 ', u'iu/kg'), (u'   vitamin c', u'', u'13,000', u'iu/kg'), (u' vitamin d max', u'', u'10,000', u'\u03bc/kg'), (u' copper', u'', u'1', u'mg/kg'), (u' vitamin e mon 10', u'', u'00', u'iu/kg')]

re.findall(regex, u'vitamin a min. 14,053 iu/kg')

# [(u'vitamin a min', u'', u'14,053 ', u'iu/kg')]

这几乎与一切相符,但你可以看到一些问题。

  • labelmin匹配,maxlabel2无匹配。

  • 我不喜欢硬编码(min|max|mon),因为可能会出现这样的情况,即单词拼写错误,并且硬编码无法捕获。

1 个答案:

答案 0 :(得分:0)

您可以使用非贪婪匹配来处理拆分这两个标签。

但是没有办法避免硬编码第二个标签。即使没有拼写变体,您也必须至少指定(min|max),否则没有理由将第二个标签与第一个标签分开(可以有任意数量的单词)。因此,您可以做的最好的事情是将该列表扩展为您可以在数据中找到的任何其他变体(可能没有那么多)。

无论如何,这是一个可行的解决方案,可以使用您提供的示例数据:

>>> regex = re.compile(ur"""
...     ((?:\w+\s+)+?)((?:min|max|mon)\.?)?
...     ([0-9., ]+)(%|[^\W\d_]+/[^\W\d_]+)
...     """, re.X | re.I | re.U)
>>> pprint(regex.findall(s))
[(u'vitamin a ', u'min.', u' 14,053 ', u'iu/kg'),
 (u'vitamin c ', u'', u'13,000', u'iu/kg'),
 (u'vitamin d ', u'max.', u' 10,000', u'\u03bc/kg'),
 (u'copper ', u'', u'1', u'mg/kg'),
 (u'vitamin e ', u'mon', u' 10.00', u'iu/kg')]