如何在Python中从列表中的字符串中获取权重和数量?

如何在Python中从列表中的字符串中获取权重和数量?,python,regex,python-2.x,Python,Regex,Python 2.x,我是Python新手,所以我对如何编写正则表达式模式以从下面的字符串列表中找到相应的权重和数量感到困惑 这就是我到目前为止一直在做的事情 import re string1 = [' (Expiry Date: 30 May 2019) 4 x Organic Infant Goat Milk' ' Follow-on Formula 3 400g', ' (Expiry on 30 May 2019) 4 x Organic Infant G

我是Python新手,所以我对如何编写正则表达式模式以从下面的字符串列表中找到相应的权重和数量感到困惑

这就是我到目前为止一直在做的事情

import re
string1 = [' (Expiry Date: 30 May 2019) 4 x Organic Infant Goat Milk'
               ' Follow-on Formula 3 400g',
           ' (Expiry on 30 May 2019) 4 x Organic Infant Goat Milk'
               ' Follow-on Formula 2 400g ',
           " [ Bellamy's ] Bellamys Organic Step 3 Toddler Milk Drink"
               " 900g x 6 tins Made In Australia  CARTON DEAL EXPIRE"
               " 06/2019 to 2020",
           ' [[1+1]] FRISO (2) 1.8kg+900g',
           " [[Carton Sales]] Bellamy's Organic Follow-On Formula"
               " Step 2 900g x 6tins",
           ' Dumex Mamil Gold Stage 4 Growing Up Kid Milk Formula'
               ' (850g) x 6',
           ' Wyeth S-26 Promise Gold Stage 4 1.6kg X 6 Tins']

m = [re.search('([0-9.]+[kgG]{1,2})', s).group(0) for s in string1] 
print m
我的输出如下:

['400g', '400g', '900g', '1.8kg', '900g', '850g', '1.6kg']
但我希望得到以下输出:

['4x400g', '4x400g', '900gx6', '1.8kg+900g', '900gx6', '850gx6', '1.6kgX6']

有什么办法可以做到这一点吗?

您的任务很复杂,StackOverflow不是一个“代码我的东西”网站,但也许这种方法可以帮您解决一些问题:

for s in string1:
  print(re.findall(
    r'((?:[0-9]+\s*[xX]\b)'
    r'|(?:\b[xX]\s*[0-9]+)'
    r'|(?:[0-9.]+\s*(?:g|kg)\b))', s))
这将打印以下输出:

['4 x', '400g']
['4 x', '400g']
['900g', 'x 6']
['1.8kg', '900g']
['900g', 'x 6']
['850g', 'x 6']
['1.6kg', 'X 6']
你仍然需要自己找出一些部分。G1.8kg和900g之间在输入中有一个+值,但可能对您有所帮助

在这种情况下通常会做什么。G在编译器中包含以下内容:

您可以编写一个标记器(又称解析器),将输入拆分为单词等标记,然后编写一个lexer,使用这些标记并生成句子等语义实体。我想这些代币应该是① 重量,② 金额x 3等。,③ 运算符+,和④ 扔掉其他东西。空白通常在这一点被剥离,因此lexer只接收介于空白之间的内容。如果现在lexer接收到一个weight-plus-weight序列,那么它应该将其组合成一个实体。如果中间有垃圾,它应该忽略加号,因为你不希望在benn's+jerry's购买5公斤或在互联网上购买300公斤会导致5公斤+300公斤


但是,这种合理的方法不是单靠Regexp完成的,我认为单靠Regexp无法解决您的任务。

最好规范前面的数量:

m = ['x'.join(i for i in re.search(r'^(?=.*?(?:(\d+)\s*x\b|\bx\s*(\d+)))?(?=.*?((?:\b[0-9]+(?:\.[0-9]+)?(?:kg|g)\b\s*?\+?\s*?)+))', s, flags=re.IGNORECASE).groups() if i) for s in string1]
根据您的示例输入,m将变成:

['4x400g', '4x400g', '6x900g', '1.8kg+900g', '6x900g', '6x850g', '6x1.6kg']

您有一个问题,您的字符串不够规则,无法由同一个正则表达式轻松处理。。。你把[number]x[number][unit]、[number][unit]x[number]和[number][unit]+[number][unit]混在一起了……我知道正则表达式的模式是不对的,但有什么办法可以得到它吗this@norok2I我想你应该写3个独立的正则表达式,然后一个接一个地试一下。我试了很多方法,我没有得到任何相应的reslut。这也是我第一次使用正则表达式。@norok2我不理解否决票。这个问题满足所有SO要求:它是可复制的,它提供输入/输出/期望输出。我不一定要投赞成票,但为什么要投反对票?您可能需要在+周围添加一些\s*来表示权重之和。否则1kg+4kg无法识别。像foo 1kg+3kg+bar这样的东西会有一个尾随+。当然。应该是\s*?但是,因为如果没有+,它将匹配一个额外的空间。