如何在不使用空格作为单词分隔符的语言(如中文)上执行PythonSplit()? [英] How to do a Python split() on languages (like Chinese) that don't use whitespace as word separator?

查看:17
本文介绍了如何在不使用空格作为单词分隔符的语言(如中文)上执行PythonSplit()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要将一个句子拆分成单词列表。

对于英语和欧洲语言,这很容易,只需使用Split()

>>> "This is a sentence.".split()
['This', 'is', 'a', 'sentence.']

但我还需要处理中文等不使用空格作为单词分隔符的句子。

>>> u"这是一个句子".split()
[u'u8fd9u662fu4e00u4e2au53e5u5b50']

这显然行不通。

如何将这样的句子拆分成单词列表?

更新:

到目前为止,答案似乎表明这需要自然语言处理技术,而且中文的单词边界是模糊的。我不确定我明白为什么。在我看来,汉语中的单词界限似乎非常明确。每个中文单词/字符都有对应的Unicode,并在屏幕上显示为单独的单词/字符。

那么模棱两可是从哪里来的呢?正如您在我的Python控制台输出中看到的那样,Python毫不费力地告诉您我的示例句子由5个字符组成:

这 - u8fd9
是 - u662f
一 - u4e00
个 - u4e2a
句 - u53e5
子 - u5b50

因此,很明显,Python可以毫不费力地判断单词/字符的边界。我只需要列表中的那些单词/字符。

unicode

只需提醒一句:使用list( '...' )(在推荐答案中是u'...')将不是,从一般意义上讲,它将为您提供unicode字符串的字符;相反,它很可能产生一系列16位代码点。对于所有"狭窄的"CPython版本来说都是如此,这占了当今绝大多数的Python安装。

当Unicode在20世纪90年代首次提出时,有人建议16位足以满足通用文本编码的所有需求,因为它允许从128个码点(7位)和256个码点(8位)移动到高达65‘536个码点。然而,人们很快发现,这是一厢情愿的想法;今天,Unicode 5.2版中定义了大约10万个码点,还有数千个码点正在等待纳入。为了实现这一点,Unicode必须从16位移动到(概念上)32位(尽管它没有充分利用32位地址空间)。

为了保持与基于Unicode仍然是16位的假设而构建的软件的兼容性,设计了所谓的代理对,其中来自特定指定块的两个16位码点被用来表示超过65‘536的码点,也就是超出Unicode所称的’基本多语言平面‘或BMP的码点,它们被戏称为该编码的’星形‘平面,因为它们相对难以捉摸,给文本处理和编码领域的工作人员带来了持续的头痛。

现在,尽管Narrow CPython在某些情况下非常透明地处理代理项对,但在其他情况下它仍然不能做正确的事情,字符串拆分是比较麻烦的情况之一。在狭义的python构建中,list( 'abc大𧰼def' )(或list( 'abcu5927U00027C3Cdef' )如果用转义编写)将导致['a', 'b', 'c', '大', 'ud85f', 'udc3c', 'd', 'e', 'f']'ud85f', 'udc3c'是代理项对。顺便说一句,'ud85fudc3c'是JSON标准希望您编写的内容,以便表示U-27C3C。这两个代码点本身都毫无用处;格式良好的Unicode字符串只能有代理项对。

因此,您希望将字符串拆分为字符的真正目的是:

from re import compile as _Re

_unicode_chr_splitter = _Re( '(?s)((?:[ud800-udbff][udc00-udfff])|.)' ).split

def split_unicode_chrs( text ):
  return [ chr for chr in _unicode_chr_splitter( text ) if chr ]

正确返回['a', 'b', 'c', '大', '𧰼', 'd', 'e', 'f'](注意:您可以重写正则表达式,这样就不需要过滤掉空字符串)。

如果您想要做的只是将文本拆分成中文字符,那么在这一点上您已经基本完成了。我不确定OP对‘单词’的概念是什么,但对我来说,这是一个句子可能分为这|是|一|个|句子和这是|一个|句子,这取决于您的观点。然而,任何超出字符和字符类(符号、空格和字母等)的概念的东西都远远超出了Unicode和Python的内置内容;您需要一些自然语言处理才能做到这一点。让我指出,虽然您的示例'yes the United Nations can!'.split()确实成功地演示了Split方法对大量数据做了一些有用的事情,但它没有将英语文本正确地解析为单词:它无法将United Nations识别为一个单词,而它错误地假设can!是一个单词,而事实显然不是。这种方法既有假阳性,也有假阴性。这可能是您想要的,也可能不是您想要的,具体取决于您的数据和您要完成的任务。

这篇关于如何在不使用空格作为单词分隔符的语言(如中文)上执行PythonSplit()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆