接连出现两个查询命中数据库(MySQL),我得到了不同的结果:

test1 = Agreement.objects.filter(pk=152, company__iregex='СитиСтро(и|й)')
test2 = Agreement.objects.filter(pk=152, company__iregex='ситистро(и|й)')

test1 <QuerySet [<Agreement: Agreement object>]>
test2 <QuerySet []>


如果字段'“СитиСтрой”'

现在,我非常确定是Cyrillics搞砸了,因为使用拉丁字母的记录可以正常工作,但是我不知道该如何解决(错误?)。有什么建议吗?

PS我做了仔细检查,这里看起来和英语和俄语的C字母相似,但是字母代码不同,所以没有混淆。

更新:
检查了Django发送给Mysql的sql。

('SELECT `dbbs_app_agreement`.`id`, `dbbs_app_agreement`.`company`, '
 'FROM `dbbs_app_agreement` WHERE (`dbbs_app_agreement`.`company` REGEXP '
 'СитиСтро(и|й) AND `dbbs_app_agreement`.`id` = 152)')


看起来不错。
试图直接从phpmyadmin查询表

SELECT `dbbs_app_agreement`.`id`, `dbbs_app_agreement`.`company` FROM `dbbs_app_agreement` WHERE (`dbbs_app_agreement`.`id` = 152 AND `dbbs_app_agreement`.`company` REGEXP 'С')


起作用了,但是

SELECT `dbbs_app_agreement`.`id`, `dbbs_app_agreement`.`company` FROM `dbbs_app_agreement` WHERE (`dbbs_app_agreement`.`id` = 152 AND `dbbs_app_agreement`.`company` REGEXP 'с')


同时没有。

如下面的@AndreyShipilov所述,使用utf8_unicode_ci归类从头开始在数据库中创建一个新表,在其中插入有问题的值(ООО“СитиСтрой”)并尝试通过phpmyadmin进行以下两个查询:

SELECT `company`.`id`, `company`.`company` FROM `company` WHERE (`company`.`id` = 0 AND `company`.`company` REGEXP 'с')
SELECT `company`.`id`, `company`.`company` FROM `company` WHERE (`company`.`id` = 0 AND `company`.`company` REGEXP 'С')


第二个有效,第一个无效。
真的很奇怪。

更新2
我组成查询的初始代码如下所示:

query_ka_name = reduce(operator.and_,
(Q(company__iregex=r'(([^\w]|^){i}([^\w]|$))'.format(i=re.sub(r'и|й', '(и|й)', item, flags=re.IGNORECASE)))


目的是检查数据库记录是否对应于从扫描中识别为公司名称的关键字数组。由于扫描仪的确很难区分и和,并且数据库记录超出了我的控制范围,因此我添加了一点东西就可以将这些字母视为一个字母。

现在,代码如下所示:

query_ka_name = reduce(operator.and_, (Q(company__iregex=tambourine(item)) for item in ka_name_listed))

def tambourine(string):
    string = re.sub(r'и|й', '(и|й)', string, flags=re.IGNORECASE)
    output = ''
    for char in string:
        if char.isalpha():
            output = '{o}({u}|{l})'.format(o=output, u=char.upper(), l=char.lower())
        else:
            output = '{o}{c}'.format(o=output, c=char)
    output = r'(([^\w]|^){i}([^\w]|$))'.format(i=output)
    return output


相比之下,这可能慢得要命,但至少可以奏效。
仍将不胜感激解决该问题。

最佳答案

“拉丁文小写字母C被认为与“西里尔小写字母ES”相同。
“西里尔小写字母I”和“西里尔小写字母I”的同上
MySQL的REGEXP使用字节而不是字符。因此,在REGEXP中只能使用不带重音的英文字母;西里尔字母不能(可靠地)工作。
MariaDB 10.0.5的REGEXP应该做得更好。参考:https://mariadb.com/kb/en/mariadb/pcre/

关于mysql - django:iregex区分大小写,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42906372/

10-12 22:51
查看更多