regex 使带有前瞻功能的正则表达式适应oracle数据库格式

bvjveswy  于 2023-01-14  发布在  Oracle
关注(0)|答案(1)|浏览(179)

在对我的前一个问题(参见How do I create a regex to avoid a repeated number with optional hyphen?)进行了有用的回答之后,我们达成了一个符合我需求的解决方案。^(?!(\d)(?:-?\1)*$)\d{2}-?\d{7}$上述正则表达式不包括以下数据:

  • 00-0000000和00000000
  • 11-1111111和111111111
  • 22日至2222222日和22222222日
  • ...
  • 99-9999999和99999999
    请注意,22-2222221有效。
    另请注意,连字符的位置可以是第一个数字之后和最后一个数字之前的任何位置

既然一切看起来都很好,我们注意到这个模式与oracle数据库REGEXP LIKE命令不兼容。
对如何适应它有什么建议吗?提前感谢。
我读到这里Oracle regular expression replacement for negative lookahead/lookbehind和提供的解决方案似乎不适合我。

ozxc1zmp

ozxc1zmp1#

鉴于您的评论:
连字符可以位于第一个数字之后和最后一个数字之前的任何位置
您可以使用以下命令在不使用正则表达式的情况下完成所有操作:

SELECT *
FROM   table_name
WHERE  -- Check that the value as the correct length
       LENGTH(value) IN (9, 10)
       -- Check that the value has the correct length without hyphens
AND    LENGTH(REPLACE(value, '-')) = 9
       -- Check that the value has only digits or hyphens
AND    TRANSLATE(value, 'a-0123456789', 'a') IS NULL
       -- Check that all the characters are not either hyphens or the same as the
       -- first character
AND    TRANSLATE(value, 'a-' || SUBSTR(value, 1, 1), 'a') IS NOT NULL;

如果连字符始终为第3个字符(如果存在),则:

SELECT *
FROM   table_name
WHERE  -- Check that the value has the correct format
       ( value LIKE '_________' OR value LIKE '__-_______' )
       -- Check that the other characters are digits
AND    TRANSLATE(
          SUBSTR(value, 1, 2) || SUBSTR(value, -7),
          'a0123456789',
          'a'
        ) IS NULL
       -- Check that all the characters are not either hyphens or the same as the
       -- first character
AND    TRANSLATE(value, 'a-' || SUBSTR(value, 1, 1), 'a') IS NOT NULL;

如果你想使用正则表达式,那么你将需要两个正则表达式:

SELECT *
FROM   table_name
WHERE  REGEXP_LIKE(value, '^\d{2}-?\d{7}$')
AND    NOT REGEXP_LIKE(value, '^(\d)\1-?\1{7}$');

或任何地方的连字符:

SELECT *
FROM   table_name
WHERE  REGEXP_LIKE(value, '^\d+-?\d+$')
AND    REGEXP_LIKE(value, '^[0-9-]{9,10}$')
AND    NOT REGEXP_LIKE(value, '^(\d)(-?\1){8}$');

或者,您可以在数据库内部启用Java,并启用use look-ahead via a Java method和正则表达式:

^(?!(\d)(-?\1){8}$)(?=(\d{9}|[0-9-]{10})$)\d+-?\d+$

fiddle

相关问题