【问题标题】:Regex to get nth occurrence of pattern (Trino)正则表达式获得第 n 次出现的模式(Trino)
【发布时间】:2022-02-14 19:20:58
【问题描述】:
WITH t(x,y) AS (
    
    VALUES 
    (1,'[2]'),
    (2,'[1, 2]'),
    (3,'[2, 1]'),
    (4,'[3, 2, 5]'),
    (5,'[3, 2, 5, 2, 4]'),
    (6,'[3, 2, 2, 0, 4]')

)

--- my wrong answer below

SELECT

REGEXP_EXTRACT(y, '(\d+,\s)?(2)(,\s\d+)?') AS _1st,
REGEXP_EXTRACT(y,'(.*?(2)){1}.*?(\d+,\s(2)(,\s\d+)?)',3) AS _2nd,
REGEXP_EXTRACT(y,'(.*?(2)){2}.*?(\d+,\s(2)(,\s\d+)?)',3) AS _3rd

FROM t

Expected ans:
| x |        y        |   1st   |   2nd   |   nth   |
| - | --------------- | ------- | ------- | ------- |
| 1 | [2]             | 2       |         |         |
| 2 | [1, 2]          | 1, 2    |         |         |
| 3 | [2, 1]          | 2, 1    |         |         |
| 4 | [3, 2, 5]       | 3, 2, 5 |         |         |
| 5 | [3, 2, 5, 2, 4] | 3, 2, 5 | 5, 2, 4 |         |
| 6 | [3, 2, 2, 0, 4] | 3, 2, 2 | 2, 2, 0 |         |

需要有关 Presto 中 REGEXP_EXTRACT 函数的正则表达式的帮助,以获取第 n 次出现的数字“2”并包括其前后的数字(如果有)

附加信息:

  • y 列中的数字不必是单个数字。
  • 数字的顺序很重要
  • 1st、2nd、3rd 指的是我正在寻找的数字的第 n 次出现
  • 将查找数字列表,而不仅仅是 2。使用 2 进行说明。

【问题讨论】:

    标签: sql json regex trino


    【解决方案1】:

    必须是正则表达式吗?

    如果您将文本 (VARCHAR) [1,2,3] 视为数组表示形式(JSON 或内部数据类型数组),则您可以使用更多函数来解决您的任务。

    查看 Presto 支持的相关功能:

    我建议将其转换为整数数组:CAST('[1,23,456]' AS ARRAY(INTEGER))

    查找第 n 次出现

    数组函数array_position(x, element, instance) → bigint 找到第 n 次出现:

    如果instance > 0,返回数组x中element的第实例的位置。

    如果instance < 0,则返回实例到数组x中元素最后一次出现的位置。

    如果没有找到匹配的元素实例,则返回0

    例子:

    SELECT CAST('[1,2,23,2,456]' AS ARRAY(INTEGER));
    SELECT array_position(2, CAST('[1,2,23,2,456]' AS ARRAY(INTEGER)), 1); -- found in position 2
    

    现在使用找到的位置来构建您的切片(相对于该位置)。

    切片和提取子数组

    1. 要么将其作为 JSON 解析为 JSON 数组。然后根据需要使用 JSON 路径进行切片(提取子数组):JSON-path 中的数组切片运算符:[start, stop, step]

    2. 或将其转换为数组,然后使用slice(x, start, length) → array

    子集数组 x 从索引 start 开始(如果 start 为负数,则从 end 开始),长度为 length。

    例子:

    SELECT json_extract(json_parse('[1,2,3]'), '$[-2, -1]');  -- the last two elements
    
    SELECT slice(CAST('[1,23,456]' AS ARRAY(INTEGER)), -2, 2); -- [23, 456]
    

    【讨论】:

    • 感谢您的评论,请问解决方案如何找到 2 的第 n 次出现并返回 2 之前和之后的数字(,2,)。我正在寻找一些数字,而不仅仅是 2,打算使用 |对于正则表达式
    • y列的数字不一定是个位数。
    • @IcySkullz,位数无关紧要,只要元素是数字(整数)并且在数组中。基本步骤是(1)将文本解析或转换为数组,(2)查找出现,(3)基于位置构建切片,(4)从数组中提取切片
    • 谢谢,现在更清楚了。我在做 CAST('[1,23,456]' AS ARRAY(INTEGER)) 时遇到了这个错误“Cannot cast varchar(10) to array(integer)”
    • @IcySkullz 你研究过这个错误信息吗?我在related question/answer 找到了帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2013-10-23
    • 2013-12-06
    相关资源
    最近更新 更多