Presto regexp_extract_all提取emoji Unicode分组异常问题排查
问题
尝试使用Presto的regexp_extract_all函数提取文本中所有emoji的Unicode字符,但当前正则表达式将每个Unicode编码拆分为数组中的单独元素,不符合预期。相关信息如下:
示例文本
{% case {{api_trigger_properties.${subj_line} | default: 1}} %} {% when 1 %} \u2614\ufe0f Today\u2019s forecast: Your favorite, no umbrella necessary. {% when 2 %} \U0001f4a6 Today\u2019s forecast: cold rain and warm, delicious {% when 3 %} \U0001f4a6 Looks like weather in {{api_trigger_properties.${city} | default: 'your neighborhood'}}! {% when 4 %} You keep dry \u2614\ufe0f We\u2019ll keep delivering \U0001f697 {% when 5 %} \U0001f327 Get out \U0001f64b\U0001f3fb\u200d\u2640\ufe0f\U0001f64b\U0001f3fe\u200d\u2640\ufe0f\U0001f64b\U0001f3ff\u200d\u2640\ufe0f {% when 6 %} ! \U0001f327 {% when 7 %} \U0001f4a6 Perfect weather for letting us drop off your {% when 8 %} Hey, just dropping in about the rainy weather {% when 9 %} Rain alert! Order in and let us weather the storm {% when 10 %} {{${first_name} | default: 'Friend' | capitalize}}, we\u2019ll handle your rainy day {% else %} You keep dry \u2614\ufe0f We\u2019ll keep delivering \U0001f697 {% endcase %}
当前查询语句
select regexp_extract_all(subject, '\\(?i)u([0-9a-f]{4,8})*|\\(?i)u([0-9a-f]{4,8})')
当前输出
{\u2614,\ufe0f,\u2019,\U0001f4a6,\u2019,\U0001f4a6,\u2614,\ufe0f,\u2019,\U0001f697,\U0001f327,\U0001f64b,\U0001f3fb,\u200d,\u2640,\ufe0f,\U0001f64b,\U0001f3fe,\u200d,\u2640,\ufe0f,\U0001f64b,\U0001f3ff,\u200d,\u2640,\ufe0f,\U0001f327,\U0001f4a6,\u2019,\u2614,\ufe0f,\u2019,\U0001f697}
期望输出
'\u2614\ufe0f','\u2019','\U0001f4a6', '\u2019', '\U0001f4a6','\u2614\ufe0f', '\u2019', '\U0001f4a6', '\u2614\ufe0f', '\U0001f697', '\U0001f327', '\U0001f64b\U0001f3fb\u200d\u2640\ufe0f\U0001f64b\U0001f3fe\u200d\u2640\ufe0f\U0001f64b\U0001f3ff\u200d\u2640\ufe0f','\U0001f327','\U0001f4a6','\u2019','\u2614\ufe0f','\u2019'
请问我的正则表达式存在什么问题?
分析与解决
你的正则表达式存在两个核心问题:
- 匹配逻辑拆分了完整序列:正则中的
|是或操作,导致它要么尝试匹配带*量词的单组Unicode编码,要么匹配单个Unicode编码,本质是把每个独立的\uXXXX/\UXXXXXXXX拆分开捕获,而非将组合成一个emoji的连续序列作为整体提取。 - 未识别emoji的组合结构:很多emoji由多个Unicode字符组合而成(比如肤色修饰符、性别符号、连接符与基础emoji的组合),原正则没有处理这种连续的关联序列。
修正后的正则查询
针对Presto的regexp_extract_all,可以使用以下正则捕获完整的emoji Unicode序列:
select regexp_extract_all(subject, '(\\u[0-9a-f]{4}|\\U[0-9a-f]{8})(?:\\u[0-9a-f]{4})*', 'i')
正则说明
(\\u[0-9a-f]{4}|\\U[0-9a-f]{8}):匹配单个基础Unicode转义序列,覆盖4位的\uXXXX和8位的\UXXXXXXXX格式。(?:\\u[0-9a-f]{4})*:非捕获组,匹配后续跟随的任意个Unicode转义序列(比如修饰符、连接符等),*表示0次或多次,确保将组合型emoji的所有关联序列作为整体捕获。'i':忽略大小写,兼容\u/\U的大小写写法。
使用该正则后,即可得到你期望的输出,每个完整emoji(包括组合型)会作为数组的单个元素被提取。
内容的提问来源于stack exchange,提问作者user7343922
相关产品推荐
相关产品推荐

