python中的阿拉伯语代码点范围

时间:2013-12-23 19:32:46

标签: python arabic python-unicode farsi

我有一个代码,梁孙实施了

#Created by Liang Sun in 2013
import re
import collections
import hashlib

class Simhash(object):
    def __init__(self, value):
        self.f = 64
        self.reg = ur'[\w\ufb50-\ufdff]'
        self.value = None

        if isinstance(value, Simhash):
            self.value = value.value
        elif isinstance(value, basestring):
            self.build_by_text(unicode(value))
        elif isinstance(value, collections.Iterable):
            self.build_by_features(value)
        elif isinstance(value, long):
            self.value = value
        elif isinstance(value, Simhash):
            self.value = value.hash
        else:
            raise Exception('Bad parameter')

    def _slide(self, content, width=2):
        return [content[i:i+width] for i in xrange(max(len(content)-width+1, 1))]

    def _tokenize(self, content):
        ans = []
        content = ''.join(re.findall(self.reg, content))
        ans = self._slide(content)
        return ans

    def build_by_text(self, content):
        features = self._tokenize(content)
        return self.build_by_features(features)

    def build_by_features(self, features):
        features = set(features) # remove duplicated features
        hashs = [int(hashlib.md5(w.encode('utf-8')).hexdigest(), 16) for w in features]
        v = [0]*self.f
        for h in hashs:
            for i in xrange(self.f):
                mask = 1 << i
                v[i] += 1 if h & mask else -1
        ans = 0
        for i in xrange(self.f):
            if v[i] >= 0:
                ans |= 1 << i
        self.value = ans

    def distance(self, another):
        x = (self.value ^ another.value) & ((1 << self.f) - 1)
        ans = 0
        while x:
            ans += 1
            x &= x-1
        return ans

我想将此代码用于阿拉伯语言文本,我向Lian Sun询问了这个问题,他说我应该用阿拉伯语代码点范围替换self.reg = ur'[\w\ufb50-\ufdff]'。我搜索并找到the Arabic Unicode block on Wikipedia,但我不知道如何使用它。

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:0)

没有“阿拉伯语代码点范围”,而是有7个特定于阿拉伯语的块,以及阿拉伯语可能使用的其他块。有关它们的详细说明,请参见Arabic script in Unicode

如果您想匹配ISO-8859-6中提供的阿拉伯字符,您只需要其中一个块的一部分,即0621-0652。

如果要匹配Unicode 1.0中可用的阿拉伯字符,那就是块0600-06FF,0750-077F和08A0-08FF。

如果你想要上下文变体,你还需要两个“表单形式”块(虽然其中一些实际上并没有被阿拉伯语使用,只有其他使用阿拉伯语脚本的语言 - 然后再次,你标记了你的问题波斯语...),FB50-FDFF和FE70-FEFF。您的原始代码与FB50-FDFF匹配这一事实意味着您需要这些。

最后,从Unicode 6.1开始,您可能需要或不需要另外两个范围,主要用于数学,10E60-10E7F和1EE00-1EEFF。

我猜你需要前5个区块,但不是最后两个区块,所以,而不是这个:

ur'[\w\ufb50-\ufdff]'

......这样做:

ur'[\w\u0600-\u06ff\u0750-\u077f\u08a0-\u08ff\ufb50-\ufdff\ufe70-\ufeff]'

但是,我不确定这是否能真正解决您的问题。原始代码使用re.findall和表示形式将文本分解为标记 - 可能是一种分裂结束字符的hacky方式(它只适用于以非常特殊,过时的方式编码的文本...) 。将其更改为findall每次运行的阿拉伯字符都会给你一个非常不同的结果。