10

文字列を取得して、140 文字に短縮する必要があります。

現在私はやっています:

if len(tweet) > 140:
    tweet = re.sub(r"\s+", " ", tweet) #normalize space
    footer = "… " + utils.shorten_urls(post['url'])
    avail = 140 - len(footer)
    words = tweet.split()
    result = ""
    for word in words:
        word += " "
        if len(word) > avail:
            break
        result += word
        avail -= len(word)
    tweet = (result + footer).strip()
    assert len(tweet) <= 140

したがって、これは英語と英語のような文字列にはうまく機能しますが、中国語の文字列では失敗し、tweet.split()配列が 1 つしか返されないためです。

>>> s = u"简讯:新華社報道,美國總統奧巴馬乘坐的「空軍一號」專機晚上10時42分進入上海空域,預計約30分鐘後抵達浦東國際機場,開展他上任後首次訪華之旅。"
>>> s
u'\u7b80\u8baf\uff1a\u65b0\u83ef\u793e\u5831\u9053\uff0c\u7f8e\u570b\u7e3d\u7d71\u5967\u5df4\u99ac\u4e58\u5750\u7684\u300c\u7a7a\u8ecd\u4e00\u865f\u300d\u5c08\u6a5f\u665a\u4e0a10\u664242\u5206\u9032\u5165\u4e0a\u6d77\u7a7a\u57df\uff0c\u9810\u8a08\u7d0430\u5206\u9418\u5f8c\u62b5\u9054\u6d66\u6771\u570b\u969b\u6a5f\u5834\uff0c\u958b\u5c55\u4ed6\u4e0a\u4efb\u5f8c\u9996\u6b21\u8a2a\u83ef\u4e4b\u65c5\u3002'
>>> s.split()
[u'\u7b80\u8baf\uff1a\u65b0\u83ef\u793e\u5831\u9053\uff0c\u7f8e\u570b\u7e3d\u7d71\u5967\u5df4\u99ac\u4e58\u5750\u7684\u300c\u7a7a\u8ecd\u4e00\u865f\u300d\u5c08\u6a5f\u665a\u4e0a10\u664242\u5206\u9032\u5165\u4e0a\u6d77\u7a7a\u57df\uff0c\u9810\u8a08\u7d0430\u5206\u9418\u5f8c\u62b5\u9054\u6d66\u6771\u570b\u969b\u6a5f\u5834\uff0c\u958b\u5c55\u4ed6\u4e0a\u4efb\u5f8c\u9996\u6b21\u8a2a\u83ef\u4e4b\u65c5\u3002']

I18N を処理するにはどうすればよいですか? これはすべての言語で意味がありますか?

それが重要な場合、私はpython 2.5.4を使用しています。

4

9 に答える 9

8

中国語は通常、単語の間に空白がなく、記号は文脈に応じて異なる意味を持つことがあります。単語の境界でテキストを分割するには、テキストを理解する必要があります。言い換えれば、あなたがやろうとしていることは一般的に簡単ではありません。

于 2009-11-15T20:57:22.313 に答える
5

中国語の単語分割や、自然言語処理におけるその他の高度なタスクについては、完全なソリューションではないにしても、 NLTKを出発点として検討してください。NLTK は豊富な Python ベースのツールキットであり、特に NL 処理技術について学習するのに適しています (まれに良いというわけではありません)。これらの問題のいくつかに対する実行可能な解決策を提供するのに十分です)。

于 2009-11-15T21:05:37.367 に答える
3

re.Uフラグは、\sUnicode 文字プロパティ データベースに従って処理されます。

ただし、Python の Unicode データベースによると、指定された文字列には明らかに空白文字が含まれていません。

>>> x = u'\u7b80\u8baf\uff1a\u65b0\u83ef\u793e\u5831\u9053\uff0c\u7f8e\u570b\u7e3d\u7d71\u5967\u5df4\u99ac\u4e58\u5750\u7684\u300c\u7a7a\u8ecd\u4e00\u865f\u300d\u5c08\u6a5f\u665a\u4e0a10\u664242\u5206\u9032\u5165\u4e0a\u6d77\u7a7a\u57df\uff0c\u9810\u8a08\u7d0430\u5206\u9418\u5f8c\u62b5\u9054\u6d66\u6771\u570b\u969b\u6a5f\u5834\uff0c\u958b\u5c55\u4ed6\u4e0a\u4efb\u5f8c\u9996\u6b21\u8a2a\u83ef\u4e4b\u65c5\u3002'
>>> re.compile(r'\s+', re.U).split(x)
[u'\u7b80\u8baf\uff1a\u65b0\u83ef\u793e\u5831\u9053\uff0c\u7f8e\u570b\u7e3d\u7d71\u5967\u5df4\u99ac\u4e58\u5750\u7684\u300c\u7a7a\u8ecd\u4e00\u865f\u300d\u5c08\u6a5f\u665a\u4e0a10\u664242\u5206\u9032\u5165\u4e0a\u6d77\u7a7a\u57df\uff0c\u9810\u8a08\u7d0430\u5206\u9418\u5f8c\u62b5\u9054\u6d66\u6771\u570b\u969b\u6a5f\u5834\uff0c\u958b\u5c55\u4ed6\u4e0a\u4efb\u5f8c\u9996\u6b21\u8a2a\u83ef\u4e4b\u65c5\u3002']
于 2009-11-16T22:43:39.363 に答える
2

プッシュ通知用にPyAPNSを使用してソリューションを試しましたが、うまくいったことを共有したかっただけです。私が抱えていた問題は、UTF-8で256バイトで切り捨てると、通知がドロップされることです。通知を機能させるには、通知が「unicode_escape」としてエンコードされていることを確認する必要がありました。これは、結果が生のUTF-8ではなくJSONとして送信されるためだと思います。とにかくここに私のために働いた関数があります:

def unicode_truncate(s, length, encoding='unicode_escape'):
    encoded = s.encode(encoding)[:length]
    return encoded.decode(encoding, 'ignore')
于 2010-01-21T03:19:52.657 に答える
1

基本的に、CJK (スペースを含む韓国語を除く) では、単語を適切に分割するために辞書検索が必要です。「単語」の正確な定義によっては、日本語はそれよりも難しい場合があります。単語のすべての語形変形 (つまり、「行こう」と「行った」) が辞書に表示されるわけではないためです。努力する価値があるかどうかは、アプリケーションによって異なります。

于 2012-02-03T06:24:07.133 に答える
1

広東語、北京語、日本語のネイティブ スピーカーと話してみると、正しいことを行うのは難しいように思えますが、現在のアルゴリズムは、インターネットの投稿のコンテキストでは、彼らにとってまだ意味があります。

つまり、彼らは「スペースを分割して最後に…を追加する」という扱いに慣れています。

だから、それを理解していない人から苦情が来るまで、私は怠け者でそれに固執するつもりです.

私の元の実装への唯一の変更は、どの言語でも不要であるため、最後の単語にスペースを強制しないことです ( 2 文字を節約するために ...&#x2026の代わりにUnicode 文字を使用します)。three dots

于 2009-11-16T22:33:44.877 に答える
0

これは単語を壊す決定を re モジュールにパントしますが、それはあなたにとって十分にうまくいくかもしれません.

import re

def shorten(tweet, footer="", limit=140):
    """Break tweet into two pieces at roughly the last word break
    before limit.
    """
    lower_break_limit = limit / 2
    # limit under which to assume breaking didn't work as expected

    limit -= len(footer)

    tweet = re.sub(r"\s+", " ", tweet.strip())
    m = re.match(r"^(.{,%d})\b(?:\W|$)" % limit, tweet, re.UNICODE)
    if not m or m.end(1) < lower_break_limit:
        # no suitable word break found
        # cutting at an arbitrary location,
        # or if len(tweet) < lower_break_limit, this will be true and
        # returning this still gives the desired result
        return tweet[:limit] + footer
    return m.group(1) + footer
于 2009-11-15T21:27:15.673 に答える
-1
于 2009-11-16T22:49:44.053 に答える