-1

我有一个代码,下面是梁孙实现的

#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]'用阿拉伯语代码点范围替换。我在 Wikipedia 上搜索并找到了阿拉伯语 Unicode 块,但我不知道如何使用它。

任何帮助表示赞赏

4

1 回答 1

0

没有“阿拉伯语代码点范围”,而是有 7 个特定于阿拉伯语的块,以及阿拉伯语可能使用的其他块。请参阅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与演示表单一起使用以将文本分解为标记——也许是一种拆分结束字符的黑客方式(这仅适用于以非常特殊且过时的方式编码的文本……)。将其更改为findall每次运行阿拉伯字符都会给您带来非常不同的结果。

于 2013-12-23T19:46:05.907 回答