有什么方法可以与 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'
,因为 👍🏻
是不同的字素。
这可能吗?
最佳答案
这是一个非常有趣的问题!
我不太确定这是否可能:
皮肤表情符号实际上是两个连接的字符(如连字)。第一个字符是黄色的手 👍,后面是表情符号皮肤修饰符 🏻
这就是浅肤色手的内部存储方式。所以,对我来说,你的结果是有道理的:
当你查询任何以👍开头的字符串时,它会返回:
👍 两个
(琐碎的)👍_🏻一个
(忽略下划线,我试图用这个来抑制自动连字)
所以,你可以看到,内部的浅肤色表情符号也是以👍开头的。这就是为什么我相信,您的查询没有按照您喜欢的方式工作。
解决方法/解决方案:
您可以在查询中添加空格。这可以确保您的 👍 角色后没有皮肤修饰符。当然,这只适用于您的情况,所有数据集在手后都有一个空格:
SELECT * FROM test WHERE name LIKE '👍 %';
您可以像这样简单地扩展
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 '👍🏿%'
您可以使用正则表达式模式匹配来排除皮肤:
SELECT * FROM test WHERE name ~ '^👍[^🏻🏼🏽🏾🏿]*$'
参见 demo:db<>fiddle (请注意, fiddle 似乎不提供自动连字,因此两个字符都分开显示在那里)
关于与 Unicode 字素匹配的 PostgreSQL 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64886585/