3

有没有办法与 Unicode 字素进行模式匹配?

举个简单的例子,当我运行这个查询时:

CREATE TABLE test (
    id SERIAL NOT NULL, 
    name VARCHAR NOT NULL,
    PRIMARY KEY (id), 
    UNIQUE (name)
);
INSERT INTO test (name) VALUES (' One');
INSERT INTO test (name) VALUES (' Two');

SELECT * FROM public.test WHERE test.name LIKE '%';

我返回了两行,而不仅仅是' Two'. Postgres 似乎只是比较代码点,但我希望它比较完整的字素,所以它应该只匹配' Two',因为是不同的字素。

这可能吗?

4

1 回答 1

3

这是一个非常有趣的问题!

我不太确定是否有可能:

实际上,蒙皮表情符号是两个连接的字符(如连字)。第一个字符是黄色的手,后面是表情符号皮肤修饰符

这就是浅肤色手在内部存储的方式。所以,对我来说,你的结果是有道理的:

当您查询任何以 开头的字符串时,它将返回:

  1. Two(琐碎的)
  2. _ One(忽略下划线,我试着用这个来抑制自动连字)

所以,你可以看到,内部的浅肤色表情符号也以 . 这就是为什么我相信您的查询不会按照您喜欢的方式工作。

变通方法/解决方案:

  1. 您可以在查询中添加空格。这样可以确保在您的角色之后没有皮肤修饰符。自然,这仅适用于您的情况,其中所有数据集在手之后都有一个空格:

    SELECT * FROM test WHERE name LIKE ' %';
    
  2. 您可以像这样简单地扩展WHERE子句:

    SELECT * FROM test 
    WHERE name LIKE '%'
        AND name NOT LIKE '%'
        AND name NOT LIKE '%'
        AND name NOT LIKE '%'
        AND name NOT LIKE '%'
        AND name NOT LIKE '%'
    
  3. 您可以使用正则表达式模式匹配来排除皮肤:

    SELECT * FROM test 
    WHERE name  ~ '^[^]*$'
    

参见demo:db<>fiddle(请注意,fiddle 似乎不提供自动连字,因此两个字符在此处分开显示)

于 2020-11-18T08:02:58.183 回答