Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:在单词边界上拆分unicode字符串_Python_Unicode_Internationalization_Character Properties - Fatal编程技术网

Python:在单词边界上拆分unicode字符串

Python:在单词边界上拆分unicode字符串,python,unicode,internationalization,character-properties,Python,Unicode,Internationalization,Character Properties,我需要获取一个字符串,并将其缩短为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 i

我需要获取一个字符串,并将其缩短为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
我应该怎么做才能让它处理I18N?这在所有语言中都有意义吗


如果有必要的话,我会使用python 2.5.4。

中文通常不会在单词之间留空格,根据上下文的不同,符号可能有不同的含义。你必须理解文本才能在单词边界处拆分它。换言之,你要做的事情并不容易。一般来说,汉语中的分词

< P>和处理自然语言的其他高级任务,如果不是一个完整的解决方案,可以看作是一个很好的起点——它是一个丰富的基于Python的工具包,特别适合于学习NL处理技术。(对于这些问题,很少有好的解决方案可以为您提供可行的解决方案)。

这将把断字的决定推到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
重新导入
def缩短(tweet,footer=”“,limit=140):
“大致在最后一个单词Break处将tweet分成两部分
在限制之前。
"""
下限值=极限值/2
#假设中断的限制未按预期工作
限制-=长度(页脚)
tweet=re.sub(r“\s+”,“”,tweet.strip())
m=re.match(r“^(.{,%d})\b(?:\W |$)%limit,tweet,re.UNICODE)
如果不是m或m.end(1)<下限:
#没有找到合适的分词符
#在任意位置切割,
#或者如果len(tweet)
在与一些母语为粤语、普通话和日语的人交谈后,似乎很难做正确的事情,但我目前的算法对他们来说在互联网帖子中仍然是有意义的

也就是说,他们习惯于“在空间上分割并在结尾处添加…”的处理方式

所以我会很懒,坚持下去,直到我收到不理解它的人的抱怨

对我的原始实现的唯一更改是不强制在最后一个单词上加空格,因为它在任何语言中都是不需要的(并且使用unicode字符…
而不是…
三个点
来保存两个字符)

将根据unicode字符属性数据库处理
\s

但是,根据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']

保存两个字符并使用省略号(
,)不是三个点!

我用Pyans尝试了推送通知的解决方案,只是想分享对我有用的东西。我遇到的问题是UTF-8中256字节的截断会导致通知被删除。我必须确保通知编码为“unicode\u escape”让它工作。我假设这是因为结果是以JSON而不是原始UTF-8的形式发送的。总之,这是对我有效的函数:

def unicode_truncate(s, length, encoding='unicode_escape'):
    encoded = s.encode(encoding)[:length]
    return encoded.decode(encoding, 'ignore')

基本上,在中日韩语中(带空格的韩语除外),你需要查字典才能正确地分词。根据你对“词”的确切定义,日语可能比这更难,因为不是一个词的所有屈折变体(即行こう" 对。“行った)将出现在词典中。是否值得努力取决于您的应用。

您正在寻找的是中文分词工具。分词不是一项容易的任务,目前还没有完全解决。有几种工具:

  • 由台湾中央研究院开发

  • 由百度工程师孙俊义开发

  • 由北京大学语言计算与机器学习小组开发

  • 如果你想要的是字符分割,它可以做到,虽然不是很有用

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

    给中文字符串加上子字符串有意义吗?比如,如果我这样做,
    s[:120]
    那仍然可读吗?你可能会得到半个单词,这可能会完全改变其含义。想象一下在前三个字母处拆分“assist”。好的,谢谢。在其他语言中,“…”是指相同的意思,还是有替代的“省略号”“Characterit我不确定该使用什么字符,但维基百科对此做了说明:据我所知,没有特殊的CJK省略号。CJK字符的宽度(“全宽”)是拉丁字符(“半宽”)的两倍,因此可能最好使用两个省略号,就像维基百科文章所说的那样:在汉语中,有时在日语中,省略号字符是通过输入两个连续的水平省略号(U+2026)来完成的。“所有这些都假定您已经确定所讨论的语言实际上是汉语,而不是日语或韩语,它们也使用CJK字符,可能有不同的省略号约定和ass/ist问题。”==通常,有时,还有其他事情?@Laurence,这取决于您典型的NL任务有多先进,以及您需要代码的生产硬化和性能优化程度。如果您处理的是TB的文本或需要低延迟响应,因此您必须部署在大型、高可扩展的并行集群上,NLTK最多只能让您使用sketch一个原型,不能为您的需求提供一个可行的解决方案;对于低容量和更具时间容限的任务,尤其是众所周知的任务,如分段,“通常”适用——但存在各种中间需求和特殊问题怪癖!-)我真的不想为分词发现培训NLP解决方案。我相信已经有人这么做了,只是想要一个预装箱的分词器。谢谢。我添加了一个检查,如果没有单词边界。对于英文字符串来说,这非常有效,但对于我的中文示例(将其加倍以使其变长),我得到的字符串长度为137个字符,而不是140个字符<代码>长度(缩短)(
    >>> s = u"简讯:新華社報道,美國總統奧巴馬乘坐的「空軍一號」專機晚上10時42分進入上海空域,預計約30分鐘後抵達浦東國際機場,開展他上任後首次訪華之旅。"
    >>> chars = list(s)
    >>> chars
    [u'\u7b80', u'\u8baf', u'\uff1a', u'\u65b0', u'\u83ef', u'\u793e', u'\u5831', u'\u9053', u'\uff0c', u'\u7f8e', u'\u570b', u'\u7e3d', u'\u7d71', u'\u5967', u'\u5df4', u'\u99ac', u'\u4e58', u'\u5750', u'\u7684', u'\u300c', u'\u7a7a', u'\u8ecd', u'\u4e00', u'\u865f', u'\u300d', u'\u5c08', u'\u6a5f', u'\u665a', u'\u4e0a', u'1', u'0', u'\u6642', u'4', u'2', u'\u5206', u'\u9032', u'\u5165', u'\u4e0a', u'\u6d77', u'\u7a7a', u'\u57df', u'\uff0c', u'\u9810', u'\u8a08', u'\u7d04', u'3', u'0', u'\u5206', u'\u9418', u'\u5f8c', u'\u62b5', u'\u9054', u'\u6d66', u'\u6771', u'\u570b', u'\u969b', u'\u6a5f', u'\u5834', u'\uff0c', u'\u958b', u'\u5c55', u'\u4ed6', u'\u4e0a', u'\u4efb', u'\u5f8c', u'\u9996', u'\u6b21', u'\u8a2a', u'\u83ef', u'\u4e4b', u'\u65c5', u'\u3002']
    >>> print('/'.join(chars))
    简/讯/:/新/華/社/報/道/,/美/國/總/統/奧/巴/馬/乘/坐/的/「/空/軍/一/號/」/專/機/晚/上/1/0/時/4/2/分/進/入/上/海/空/域/,/預/計/約/3/0/分/鐘/後/抵/達/浦/東/國/際/機/場/,/開/展/他/上/任/後/首/次/訪/華/之/旅/。