5

我正在尝试解析一个句子(或文本行),其中您有一个句子,并且可以选择在同一行上跟随一些键/值对。键/值对不仅是可选的,而且是动态的。我正在寻找类似的结果:

输入:

"There was a cow at home. home=mary cowname=betsy date=10-jan-2013"

输出:

Values = {'theSentence' : "There was a cow at home.",
          'home' : "mary",
          'cowname' : "betsy",
          'date'= "10-jan-2013"
         }

输入:

"Mike ordered a large hamburger. lastname=Smith store=burgerville"

输出:

Values = {'theSentence' : "Mike ordered a large hamburger.",
          'lastname' : "Smith",
          'store' : "burgerville"
         }

输入:

"Sam is nice."

输出:

Values = {'theSentence' : "Sam is nice."}

感谢您的任何输入/方向。我知道这些句子似乎是一个家庭作业问题,但我只是一个 python 新手。我知道这可能是一个正则表达式解决方案,但我不是最好的正则表达式。

4

9 回答 9

4

我会使用re.sub

import re

s = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"

d = {}

def add(m):
    d[m.group(1)] = m.group(2)

s = re.sub(r'(\w+)=(\S+)', add, s)
d['theSentence'] = s.strip()

print d

如果您愿意,这里是更紧凑的版本:

d = {}
d['theSentence'] = re.sub(r'(\w+)=(\S+)',
    lambda m: d.setdefault(m.group(1), m.group(2)) and '',
    s).strip()

或者,也许,findall是一个更好的选择:

rx = '(\w+)=(\S+)|(\S.+?)(?=\w+=|$)'
d = {
    a or 'theSentence': (b or c).strip()
    for a, b, c in re.findall(rx, s)
}
print d
于 2013-07-22T19:04:31.150 回答
1

第一步是做

inputStr = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"
theSentence, others = str.split('.')

然后你会想要分手“其他人”。玩弄 split() (你传入的参数告诉 Python 用什么分割字符串),看看你能做什么。:)

于 2013-07-22T18:53:12.107 回答
1

如果您的句子保证以 结尾.,那么,您可以遵循以下方法。

>>> testList = inputString.split('.')
>>> Values['theSentence'] = testList[0]+'.'

对于其余的值,只需执行即可。

>>> for elem in testList[1].split():
        key, val = elem.split('=')
        Values[key] = val

给你一个Values这样的

>>> Values
{'date': '10-jan-2013', 'home': 'mary', 'cowname': 'betsy', 'theSentence': 'There was a cow at home.'}
>>> Values2
{'lastname': 'Smith', 'theSentence': 'Mike ordered a large hamburger.', 'store': 'burgerville'}
>>> Values3
{'theSentence': 'Sam is nice.'}
于 2013-07-22T18:58:21.673 回答
1

假设可能只有 1 个点,它将句子和分配对分开:

input = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"
sentence, assignments = input.split(". ")

result = {'theSentence': sentence + "."}
for item in assignments.split():
    key, value = item.split("=")
    result[key] = value

print result

印刷:

{'date': '10-jan-2013', 
 'home': 'mary', 
 'cowname': 'betsy', 
 'theSentence': 'There was a cow at home.'}
于 2013-07-22T18:58:32.213 回答
0

假设=不会出现在句子本身中。这似乎比假设句子以 a 结尾更有效.

s = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"

eq_loc = s.find('=')
if eq_loc > -1:
    meta_loc = s[:eq_loc].rfind(' ')
    s = s[:meta_loc]
    metastr = s[meta_loc + 1:]

    metadict = dict(m.split('=') for m in metastr.split())
else:
    metadict = {}

metadict["theSentence"] = s
于 2013-07-22T19:00:25.887 回答
0

所以像往常一样,有很多方法可以做到这一点。这是一种基于正则表达式的方法,用于查找键=值对:

import re

sentence = "..."

values = {}
for match in re.finditer("(\w+)=(\S+)", sentence):
    if not values:
        # everything left to the first key/value pair is the sentence                                                                               
        values["theSentence"] = sentence[:match.start()].strip()
    else:
        key, value = match.groups()
        values[key] = value
if not values:
    # no key/value pairs, keep the entire sentence
    values["theSentence"] = sentence

这假定键是 Python 样式的标识符,并且值由一个或多个非空白字符组成。

于 2013-07-22T19:01:53.067 回答
0

假设第一个句点将句子与值分开,您可以使用以下内容:

#! /usr/bin/python3

a = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"

values = (lambda s, tail: (lambda d, kv: (d, d.update (kv) ) ) ( {'theSentence': s}, {k: v for k, v in (x.split ('=') for x in tail.strip ().split (' ') ) } ) ) (*a.split ('.', 1) ) [0]

print (values)
于 2013-07-22T19:04:26.453 回答
0

没有人发布可理解的单行。问题已得到解答,但必须在一行中完成,这是 Python 方式!

{"theSentence": sentence.split(".")[0]}.update({item.split("=")[0]: item.split("=")[1] for item in sentence.split(".")[1].split()})

嗯,不是很优雅,但它完全在一条线上。甚至没有进口。

于 2013-07-22T19:12:21.293 回答
0

使用正则表达式 findall。第一个捕获组是句子。| 是第二个捕获组的 or 条件:一个或多个空格、一个或多个字符、等号和一个或多个非空格字符。

s = "There was a cow at home. home=mary cowname=betsy date=10-jan-2013"
all_matches = re.findall(r'([\w+\s]+\.{1})|((\s+\w+)=(\S+))',s)
d={}
for i in np.arange(len(all_matches)):
   #print(all_matches[i])
   if all_matches[i][0] != "":
       d["theSentence"]=all_matches[i][0]
   else:
       d[all_matches[i][2]]=all_matches[i][3]
   
print(d)

输出:

  {'theSentence': 'There was a cow at home.', ' home': 'mary', ' cowname': 'betsy', ' date': '10-jan-2013'}
于 2021-06-15T16:39:59.793 回答