使用python从不规则值中提取数字

时间:2018-12-18 09:19:19

标签: python regex

我有如下数据:

Format,Message,time
A,gn@2 ab@1 yl@5 rd@20 pp@40,3
B,w:w23w4w5w6w7gn@3 gn@7 yl@20 ss@25 rd@50,21
C,cc@1 fgn@4 yl@9 rd@20,22
D,rg@1 fedsf@5 rww@10 yl@20 rd@26,30

我的预期结果是提取gn,yl和rd之后的数字

Format,Message,time,gn,yl,rd
A,gn@2 ab@1 yl@5 rd@20 pp@40,3,2,5,20
B,w:w23w4w5w6w7gn@3 an@7 yl@20 ss@25 rd@50,21,3,20,50
C,cc@1 fgn@4 yl@9 rd@20,22,4,9,20
D,rg@1 fedsf@5 rww@10 yl@20 rd@26,30,0,20,26
截至目前,

我无法获取yl和rd,但无法提取gn之后的数字。请注意,gn元素可能由gn之前的其他字符组成,而数字在gn @之后是必需的

def f(mess):
    p1 = mess.find('yl')
    p2 = mess.find('rd')
    b = mess[p1+3:].split(' ')[0]
    c = mess[p2+3:].split(' ')[0]
    return int(b),int(c)
id['vals'] = id['Message'].apply(f) #with this im able to get the numbers from yl and rd

4 个答案:

答案 0 :(得分:1)

让我们逐步解决这个问题。

  1. 仅获取您感兴趣的行。
  2. 删除可能对我们无用的数据。
  3. 使用剩下的数据提取信息。

让我们假设我将输入存储在变量data中,并且我需要将输出存储在称为final的元组列表中。这就是我解决这个问题的方法。

useful = data.split('\n')[1:]  ## Step 1
code = [x[1].strip() for x in useful.split(',')] ## Step 2
gn_value = -1
yl_value = -1
rd_value = -1
for line in code:
    for each in line.split(' '): ## Step 3
        if 'gn@' in each:
            gn_value = int(each[each.find('gn@')+3:])
        elif 'yl@' in each:
            yl_value = int(each[each.find('yl@')+3:])
        elif 'rd@' in each:
            rd_value = int(each[each.find('rd@')+3:])
    final.append(gn_value, yl_value, rd_value)

注意:以上解决方案是在假设任何给定行中没有多次出现任何值的前提下开发的。

让我知道您是否有任何疑问。

答案 1 :(得分:0)

尝试使用以下表达式:

mess = 'gn@2 ab@1 yl@5 rd@20 pp@40'
result = [ int(m.split('@')[1])  for m in mess.split() if m.split('@')[0] in ['gn', 'yl', 'rd'] ]

答案 2 :(得分:0)

使用正则表达式。

演示:

import re
s = """A,gn@2 ab@1 yl@5 rd@20 pp@40,3,2,5,20
B,w:w23w4w5w6w7gn@3 an@7 yl@20 ss@25 rd@50,21,3,20,50
C,cc@1 fgn@4 yl@9 rd@20,22,4,9,20
C,cc@1 yl@9 rd@20,22,4,9,20"""

for line in s.splitlines():
    gn = re.search(r"gn@(.?\S)", line)
    if gn:
        gn = gn.group(1)

    yl = re.search(r"yl@(.?\S)", line)
    if yl:
        yl = yl.group(1)

    rd = re.search(r"rd@(.?\S)", line)
    if rd:
        rd = rd.group(1)
    print(gn, yl, rd)

输出:

2 5 20
3 20 50
4 9 20
None 9 20

答案 3 :(得分:0)

我以为我也会添加变体

mess = """
A,gn@2 ab@1 yl@5 rd@20 pp@40,3
B,w:w23w4w5w6w7gn@3 gn@7 yl@20 ss@25 rd@50, 21
C,cc@1 fgn@4 yl@9 rd@20, 22
"""

for row in mess.strip().splitlines():
    print("ROW:", row)
    for col in row.split(" "):
        try:
            k, v = col.split('@')
            print("%s=%d" % (k[-2:], int(v.split(',', 1)[0])))
        except:
            print("leftover=%s" % col)
    print()

这会产生:

ROW: A,gn@2 ab@1 yl@5 rd@20 pp@40,3
gn=2
ab=1
yl=5
rd=20
pp=40

ROW: B,w:w23w4w5w6w7gn@3 gn@7 yl@20 ss@25 rd@50, 21
gn=3
gn=7
yl=20
ss=25
rd=50
leftover=21

ROW: C,cc@1 fgn@4 yl@9 rd@20, 22
cc=1
gn=4
yl=9
rd=20
leftover=22

无论您是否有多个重复的键或值,我都很容易将它们放入列表的字典中:) 无需多个条件和挑选。所有键=值对都是可访问的。