我在 堆栈溢出 (请让我知道我是否必须删除)。

我正在处理DB2数据库,据我所知,不支持Regexp(没有其他库)。

因此,我无法实施与本文中解释的类似的东西”将正则表达式匹配到SQL的力量"

您知道我是否可以使用SQL语句“模仿”这样的正则表达式?

^a [aofdmep] {1} [az] {1} [a-Z0-9] {4} [sidbfkfpo] {1}

编辑

在上面的假设中,我发现我的情况是可以接受的 在哪里 喜欢谓词:

user_name不喜欢“ a_______”的地方

但这是不安全的,并且不涵盖我没有固定的炭的其他情况。

有帮助吗?

解决方案

首先, {1}S是多余的,所以实际上只是:

^[aofdmep][a-z][a-z0-9]{4}a[sidbfkfpo]

这实际上是一个非常简单的模式...它只是在查看字符串的前8个字符,并且始终是一个固定的长字符串,因此您可以构建所有排列的表格,然后做:

WHERE SUBSTR(string_to_match, 1, 8) IN (
  SELECT valid_prefixes FROM table_of_things_to_match
)

不幸的是,它是7*26*36^4*9 ... 27.5亿可能的组合,但是,固定字符串,因此您可以做:

WHERE SUBSTR(string_to_match, 1, 1) IN ('a','o','f','d','m','e','p')
  AND SUBSTR(string_to_match, 2, 1) IN ('a','b','c','d' ... 'z')
  AND SUBSTR(string_to_match, 3, 1) IN ('a','b','c','d' ... 'z','0','1' ... '9')
  AND SUBSTR(string_to_match, 4, 1) IN ('a','b','c','d' ... 'z','0','1' ... '9')
  AND SUBSTR(string_to_match, 5, 1) IN ('a','b','c','d' ... 'z','0','1' ... '9')
  AND SUBSTR(string_to_match, 6, 1) IN ('a','b','c','d' ... 'z','0','1' ... '9')
  AND SUBSTR(string_to_match, 7, 1) = 'a'
  AND SUBSTR(string_to_match, 8, 1) IN ('s','i','d','b','f','k','p','o')

(填写 ... 当然)

糟糕,有两个 f在最后一个角色类中,因此只有24.5亿个排列。

我不会假装它会很快……它可能不会,但是它会为您带来所需的模式。如果您倾向于做很多事情,我可能会构建一个字符表,因此您可以轻松地选择alpha / numeric或alpha-numeric。

其他提示

由于这个古老的问题已经被挖出了

select whatever
from users
where
   xmlcast(
     xmlquery('fn:matches($USER_NAME,"^a[aofdmep][a-z][a-z0-9]{4}[sidbfkfpo]")') 
     as integer) = 1

XMLQUERY 上面调用Xquery matches 对列的功能 USER_NAME. 。结果是XML boolean, , 所以 XMLCAST 用于将其转换为SQL数据类型。

SELECT * FROM
   (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1)
WHERE substr(MyString,1,1) = 'a' 
AND   substr(MyString,2,1) IN ('a','o','f','d','m','e','p')
AND   substr(MyString,3,1) BETWEEN 'a' AND 'z'
AND  (substr(MyString,4,1) BETWEEN 'a' AND 'z' 
   OR substr(MyString,4,1) BETWEEN '0' AND '9')
AND  (substr(MyString,5,1) BETWEEN 'a' AND 'z' 
   OR substr(MyString,5,1) BETWEEN '0' AND '9')
AND  (substr(MyString,6,1) BETWEEN 'a' AND 'z' 
   OR substr(MyString,6,1) BETWEEN '0' AND '9')
AND  (substr(MyString,7,1) BETWEEN 'a' AND 'z' 
   OR substr(MyString,7,1) BETWEEN '0' AND '9')
AND   substr(MyString,8,1) IN ('s','i','d','b','f','k','p','o');

在Leigh Riffel和Joe的答案的基础上,您可能会考虑使用诸如单个角色列表或具有多个角色范围时的使用。

SELECT *
  FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) T
 WHERE substr(MyString,1,1) = 'a'
   AND 'aofdmep' like '%'||substr(MyString,2,1)||'%'
   AND substr(MyString,3,1) BETWEEN 'a' AND 'z'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,4,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,5,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,6,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,7,1)||'%'
   AND 'sidbfkpo' like '%'||substr(MyString,8,1)||'%'
;

由于您多次使用相同的字符列表,因此您还可以考虑使用交叉连接的常数列。

SELECT *
  FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) T
  CROSS JOIN (SELECT 'abcdefghijklmnopqrstuvwxyz0123456789' alphanum FROM SYSIBM.SYSDUMMY1) T2
 WHERE substr(MyString,1,1) = 'a'
   AND 'aofdmep' like '%'||substr(MyString,2,1)||'%'
   AND substr(MyString,3,1) BETWEEN 'a' AND 'z'
   AND alphanum like '%'||substr(MyString,4,1)||'%'
   AND alphanum like '%'||substr(MyString,5,1)||'%'
   AND alphanum like '%'||substr(MyString,6,1)||'%'
   AND alphanum like '%'||substr(MyString,7,1)||'%'
   AND 'sidbfkpo' like '%'||substr(MyString,8,1)||'%'
;

您的示例不需要,但是十字架连接的“表”可以定义多个命名字符类列。

Regexp_like现在可以在iSeries的DB2中使用 - 请参阅:http://www.itjungle.com/fhg/fhg051915-story01.html

在Z/OS的DB2中,SQL将包括通过如下传递

select whatever
from users
where
   xmlcast(
     xmlquery('fn:matches($USER_NAME,"^a[aofdmep][a-z][a-z0-9]{4}[sidbfkfpo]")'
      PASSING USER as "USER_NAME") 
     as integer) = 1
许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top