您的正则表达式看起来有些混乱和无效,而且看起来也不能完全满足您的需求。我将这个表达式读为字符串:
- 必须以一位或多位数字开头,至少3次或多次
- 让我感到困惑的部分是“ +”是一个量词,无法用{3,}进行量化,但是以某种方式不会对我产生错误
- 可选地后跟破折号或加号
- 后跟一个大写字符零或一遍(根据需要返回)
- 其后以零或一小写字符结尾,并以小写字符结尾(根据需要提供)
问题
您说您的字符串必须包含3个字符和至少2个不同的数字,数字是字符,但是我不确定您是不是指3个字母...
- 您是否认为数字是字符?
- 字符顺序重要吗?
- 能否提供您收到的错误示例?
注释
检查与第二个数字不同的第二个数字涉及具有反向引用的超前查找的概念。 Snowflake不支持反向引用。
与正则表达式进行模式匹配有关的一件事是顺序会有所不同。如果顺序对您而言不重要,那么您将有多种模式可以匹配。
示例
下面是如何分别测试需求的每个部分。我提供了一些regexp_substr函数,以演示提取如何工作以检查是否再次存在。
取消注释WHERE子句以查看已过滤的数据集。过滤器被写为表达式,因此您可以删除任何/所有regexp_ *列。
select randstr(36,random(123)) as r_string,length(r_string) AS length,regexp_like(r_string,'^[0-9]+{3,}[-+]?[A-Z]?[a-z]?$') as reg,'.*[A-Za-z]{3,}.*') as has_3_consecutive_letters,'.*\\d+.*\\d+.*') as has_2_digits,regexp_substr(r_string,'(\\d)',1,1) as first_digit,2) as second_digit,first_digit <> second_digit as digits_1st_not_equal_2nd,not(regexp_instr(r_string,1),2)) as first_digit_does_not_appear_again,has_3_consecutive_letters and has_2_digits and first_digit_does_not_appear_again as test
from table(generator(rowcount => 10))
//where regexp_like(r_string,}.*') // has_3_consecutive_letters
// and regexp_like(r_string,'.*\\d+.*\\d+.*') // has_2_digits
// and not(regexp_instr(r_string,2)) // first_digit_does_not_appear_again
;
,
假设数字必须是连续的,则可以使用javascript UDF在具有最大不同数字位数的字符串中查找数字:
create or replace function f(S text)
returns float
language javascript
returns null on null input
as
$$
const m = S.match(/\d+/g)
if (!m) return 0
const lengths = m.map(m=> [...new Set (m.split(''))].length)
const max_length = lengths.reduce((a,b) => Math.max(a,b))
return max_length
$$
;
我相信,结合WHERE条款,这可以满足您的需求
select column1,f(column1) max_length
from t
where max_length>1 and length(column1)>2 and column1 rlike '[\\w\\d-]+';
屈服:
COLUMN1 | MAX_LENGTH
------------------------+-----------
abc123def567ghi1111_123 | 3
123 | 3
111222 | 2
假设此输入:
create or replace table t as
select * from values ('abc123def567ghi1111_123'),('xyz111asdf'),('123'),('111222'),('abc 111111111 abc'),('12'),('asdf'),('123 456'),(null);
如果数字不必是连续的(即计算字符串中的不同数字),则该功能甚至更简单。然后核心逻辑变为:
const m = S.match(/\d/g)
if (!m) return 0
const length = [...new Set (m)].length
return length
希望有帮助!
本文链接:https://www.f2er.com/2898369.html