Oracle REGEXP_LIKE前瞻性和前瞻性解决方法



我正在努力构建一个适用于Oracle的regexp_like语句。我需要比较一系列行,每一行都有一个包含逗号分隔的数字集的字段。(总是数字(。我需要根据这些数字的变化来激活和停用账户(每天(。

这里有几个字段的示例。(下面的每一行都是字段中的结果(

9,18,31,32,50,725
17,20,31,32,50,725
17,18,20,22,50,725
9,18,31,49,50,500
49,22,9,25,222
18,18,31,9,50,725
49,31,9,25,292

我需要查找具有以下一个或多个数字的行。9、20、22、50。(代码中的其他位置可能只需要9个,或者只需要20和22个。但这个原则是成立的。如果数字是500,则无法选择。它一定是50。

以下正则表达式适用于python、我的notepad++搜索和在线正则表达式生成器:

((?<![1-9])9|(?<![1-9])20(?![1-9])|(?<![1-9])22(?![1-9])|(?<![1-9])50(?![1-9]))

它依赖于消极的前瞻和消极的向后看。但由于Oracle不支持环视,我被难住了。

这里有一段示例代码,如果我在不查找的情况下使用regexp,它就会起作用。

DECLARE 
v_search_string    varchar2(60);
BEGIN
v_search_string := '49,31,9,25,50,292';
IF REGEXP_LIKE( v_search_string, '((?<![1-9])9|(?<![1-9])20(?![1-9])|(?<![1-9])22(?![1-9])|(?<![1-9])50(?![1-9]))')
THEN
dbms_output.put_line('Yes');
ELSE
dbms_output.put_line('No');
END IF;
--dbms_output.put_line('Yes');
END;

在这种情况下,我应该在dbms_output中得到"Yes",因为它应该匹配"50"。

有什么想法吗?附言:我对有人说";嘿,傻,这样做会更容易">

我甚至不会在这里使用regex:

DECLARE 
v_search_string    varchar2(60);
BEGIN
v_search_string := '49,31,9,25,50,292';
IF ',' || v_search_string || ',' LIKE '%,9,%' OR ',' || v_search_string || ',' LIKE '%,20,%' OR ',' || v_search_string || ',' LIKE '%,22,%' OR ',' || v_search_string || ',' LIKE '%,50,%'
THEN
dbms_output.put_line('Yes');
ELSE
dbms_output.put_line('No');
END IF;
--dbms_output.put_line('Yes');
END;

这里要明确的是,我们将,49,31,9,25,50,292,与例如%,9,%进行比较,以在CSV字符串中的某个位置搜索数字9。这种方法实际上可能优于REGEXP_LIKE,因为它不使用正则表达式。

...
where regexp_like(your_string, '(,|^)(9|20|22|50)(,|$)')
...

总的来说,我同意Tim Biegeleisen的观点——尽可能多地使用标准字符串函数。

在这种情况下,单个regexp搜索可能比同一字符串的四个标准字符串搜索做得更好;regexp方法更灵活。您可以将正则表达式重写为

'(,|^)(' || things_to_search || ')(,|$)'

并让things_to_search是一个用户输入,或者来自一个表,等等(它将是一个必须匹配的数字的管道分隔列表(。如果将其用作绑定变量,则可以获得软解析的好处(无论何时更改列表,都不需要再次解析查询(。

@mathguy。感谢你把我复杂的发言变成一个单一、清晰的发言。

以逗号或行首开头;以逗号或行尾结尾;加上在中间的东西。更改要搜索的内容的变量,然后让r rip。

这是修改后的sql。

DECLARE 
v_search_string    varchar2(60);
v_things_to_search    varchar2(60);
BEGIN
v_search_string := '9,31,29,25,520,500';
v_things_to_search := '9|20|22|50';
IF REGEXP_LIKE( v_search_string, '(,|^)(' || v_things_to_search || ')(,|$)')
THEN
dbms_output.put_line('Yes');
ELSE
dbms_output.put_line('No');
END IF;
--dbms_output.put_line('Yes');
END;

相关内容

最新更新