字符串替换字典,标点符号并发症(String replacement with dictionary

2019-07-04 22:00发布

我试图写一个函数过程(S,d)通过使用字典来取代他们的全部意义的字符串缩写。 其中s是字符串输入和d是字典。 例如:

>>>d = {'ASAP':'as soon as possible'}
>>>s = "I will do this ASAP.  Regards, X"
>>>process(s,d)
>>>"I will do this as soon as possible.  Regards, X"

我已经使用分割功能分割字符串和比较字典中的每个部分尝试。

def process(s):
    return ''.join(d[ch] if ch in d else ch for ch in s)

但是,它返回我完全相同的字符串。 我有一个怀疑,代码没有在原来的字符串,因为句号的作品背后尽快。 如果是这样,我怎么忽略了标点符号,并得到尽快更换?

Answer 1:

这里有一个方法与单个正则表达式来做到这一点:

In [24]: d = {'ASAP':'as soon as possible', 'AFAIK': 'as far as I know'}

In [25]: s = 'I will do this ASAP, AFAIK.  Regards, X'

In [26]: re.sub(r'\b' + '|'.join(d.keys()) + r'\b', lambda m: d[m.group(0)], s)
Out[26]: 'I will do this as soon as possible, as far as I know.  Regards, X'

与基于版本str.replace()这个观察单词边界,因此不会取代碰巧出现在其他字(“取”,例如“等”),中间的缩写。

此外,与大多数(全部?)其他迄今提出的解决方案,它遍历输入字符串只有一次,不管有多少搜索词中有字典。



Answer 2:

你可以这样做:

def process(s,d):
    for key in d:
        s = s.replace(key,d[key])
    return s


Answer 3:

这里是一个可行的解决方案:使用re.split() ,和分割由字边界(保留间质性字符):

''.join( d.get( word, word ) for word in re.split( '(\W+)', s ) )

一个显著的差异,该代码具有从沃恩的或希娜的回答是,这个代码利用O(1)词典的查找时间的优势,而他们的解决方案看字典中的每一个关键。 这意味着,当s短, d是非常大的,他们的代码将显著需要更长的时间来运行。 此外,字的部分仍然会在他们的解决方案替换为:如果d = { "lol": "laugh out loud" }s="lollipop"他们的解决方案将错误地产生"laugh out loudlipop"



Answer 4:

使用正则表达式:

re.sub(pattern,replacement,s)

在您的应用程序:

ret = s
for key in d:
    ret = re.sub(r'\b'+key+r'\b',d[key],ret)
return ret

\ b词的开头或结尾匹配。 感谢保罗的评论



Answer 5:

相反,用空格分割的,可以使用:

split("\W")

它将由任何非这将是一个单词的一部分字符分割。



Answer 6:

    python 3.2

    [s.replace(i,v) for i,v in d.items()]


Answer 7:

这是字符串替换,以及(+1至@VaughnCato)。 本品采用reduce功能,通过你的字典迭代,更换密钥的任何实例与值的字符串中。 s在这种情况下是在每次迭代的累加器,这是减少(即送入替换功能),维护所有过去的替代(也应按照上述@ PaulMcGuire的角度来看,这种替代键启动最长和最短结束)。

In [1]: d = {'ASAP':'as soon as possible', 'AFAIK': 'as far as I know'}

In [2]: s = 'I will do this ASAP, AFAIK.  Regards, X'

In [3]: reduce(lambda x, y: x.replace(y, d[y]), sorted(d, key=lambda i: len(i), reverse=True), s)
Out[3]: 'I will do this as soon as possible, as far as I know.  Regards, X'

至于为什么你的函数没有返回你所期望的-当你通过迭代s没有的话- ,你实际上是通过字符串的字符迭代。 你的版本可以通过迭代进行调整s.split()这将是词的列表),但你再碰上一个问题,即标点符号引起的话不符合你的字典。 你可以把它导入到匹配string和剥离出来string.punctuation从每一个字,但会从最终的字符串删除标点符号(所以正则表达式将可能是最好的选择,如果更换不工作)。



文章来源: String replacement with dictionary, complications with punctuation