【问题标题】:can't get correct python regex with this string that contains unicode无法使用包含 unicode 的字符串获得正确的 python 正则表达式
【发布时间】:2014-12-04 17:32:38
【问题描述】:

我有这个字符串:

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')]

这几乎匹配所有内容,但您会发现一些问题。

  • label 匹配 min,maxlabel2 不匹配。

  • 我不喜欢硬编码(min|max|mon),因为在某些情况下,单词被拼错成其他东西,而硬编码无法捕捉到它。

【问题讨论】:

    标签: python regex unicode


    【解决方案1】:

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

    但是没有办法避免硬编码第二个标签。即使没有拼写变体,您也必须至少指定(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')]
    

    【讨论】:

    • 啊,好吧。我将您的正则表达式修改为re.compile(ur"""((?:\w+\s+)+?)((?:min|max|mon))?\.?([0-9., ]+)(%|[^\W\d_]+/[^\W\d_]+)""", re.X | re.I | re.U)(只是将\.? 移到外面,这样它就不会用label2 捕获期间)。感谢您的帮助。
    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多