2

辞書を使用して、文字列内の略語を完全な意味に置き換える関数 process(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"

split 関数を使用して文字列を分離し、各部分を辞書と比較してみました。

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

ただし、まったく同じ文字列が返されます。元の文字列の ASAP の後ろに終止符があるため、コードが機能しないのではないかと疑っています。その場合、句読点を無視して ASAP を交換するにはどうすればよいですか?

4

7 に答える 7

5

単一の正規表現でそれを行う方法は次のとおりです。

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()、これは単語の境界を監視するため、他の単語の途中に表示される略語(たとえば、「fetch」の「etc」)を置き換えることはありません。

また、これまでに提示された他のほとんどの(すべて?)ソリューションとは異なり、辞書に検索語がいくつあるかに関係なく、入力文字列を1回だけ繰り返します。

于 2012-12-11T16:32:39.920 に答える
2

これが実用的な解決策です: re.split()を使用し、単語の境界で分割します (インタースティシャル文字を保持します):

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

このコードが Vaughn または Sheena の回答と大きく異なる点の 1 つは、このコードが辞書の O(1) ルックアップ時間を利用しているのに対し、それらのソリューションは辞書内のすべてのキーを調べていることです。これは、sが短くてd非常に大きい場合、コードの実行に非常に長い時間がかかることを意味します。さらに、単語の一部は解決策で置き換えられます: ifd = { "lol": "laugh out loud" }s="lollipop"その解決策は間違って を生成し"laugh out loudlipop"ます。

于 2012-12-11T06:43:02.393 に答える
2

次のようなことができます。

def process(s,d):
    for key in d:
        s = s.replace(key,d[key])
    return s
于 2012-12-11T05:49:16.457 に答える
1

正規表現を使用します:

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 は、単語の先頭または末尾に一致します。ポールさん、コメントありがとうございます

于 2012-12-11T05:48:33.337 に答える
0
    python 3.2

    [s.replace(i,v) for i,v in d.items()]
于 2012-12-11T16:14:36.277 に答える
0

これも文字列の置換です(@VaughnCatoに+1)。これは、reduce関数を使用して辞書を反復処理し、文字列内のキーのインスタンスを値に置き換えます。sこの場合、アキュムレータであり、反復ごとに削減され (つまり、replace 関数に供給され)、過去のすべての置換を維持します (また、上記の @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()が、句読点が原因で単語が辞書と一致しないという問題に遭遇します。各単語をインポートして削除することで一致させることができますがstringstring.punctuation最終的な文字列から句読点が削除されます (したがって、置換が機能しない場合は、正規表現が最適なオプションになる可能性があります)。

于 2012-12-11T06:11:47.360 に答える
0

スペースで区切る代わりに、次を使用します。

split("\W")

単語の一部となる文字ではないものによって分割されます。

于 2012-12-11T05:48:28.983 に答える