0

我想知道如何在 Oracle 中编写一个可以检测以下表达式的正则表达式:

aaaaabbb
aaaaaccc
aaaaaddd
...
aaaaazzz

我努力了:

a{5}\w{3}

a{5}[a-z]{3}

a{5}(\w)\1{2}

但如果失败,它也会检测到aaaaadef

谢谢你的帮助。

4

4 回答 4

1

为了进一步扩展Felipe关于不需要正则表达式的答案,这里根本不需要任何复杂的东西。如果我窃取了他的表创建脚本,以下将起作用:

SQL> select *
  2    from t1
  3   where replace(substr(field1, 1, 5), 'a') is null
  4     and substr(field1,6,1) = substr(field1,7,1)
  5     and substr(field1,6,1) = substr(field1,8,1);

FIELD1
---------------------------------------------------------------

aaaaabbb
aaaaaccc
aaaaaddd
aaaaafff

如果你想让它稍微整洁一些,你可以使用REGEXP_COUNT(),但我看不出它有什么不同:

SQL> select *
  2    from t1
  3   where regexp_count(substr(field1, 1, 5), 'a') = 5
  4     and regexp_count(substr(field1,6), substr(field1,6,1)) = 3;

FIELD1
----------------------------------------------------------------------

aaaaabbb
aaaaaccc
aaaaaddd
aaaaafff

这是一个要演示的SQL Fiddle 。

于 2013-05-29T12:07:37.723 回答
0
with x as (
select 'aaaaabbb' as val from dual
union
select 'aaaaaccc' as val from dual
union
select 'aaaaadef' as val from dual
union
select 'aaaaa___' as val from dual
)
select *
from x
where regexp_like(x.val, 'a{5}([a-z])\1{2}')

输出:

aaaaabbb
aaaaaccc

请注意, 'a{5}(\w)\1{2}' 不起作用,因为 (\w) 将匹配字母数字和下划线,并且从您的示例中您只需要 az 。

于 2013-05-29T13:25:51.073 回答
0

你想从中匹配什么? 编辑我想我现在明白你在找什么,所以调整了下面的正则表达式

您将需要类似oracle 的反向引用的东西

^a{5}((?!a)\w)\1{2}?$ // will match aaaaaddd but not bbbbbddd - this is probably what you need

编辑 2如果您在数据库中而不是在访问数据库的 java 中执行此操作,那么您可能必须放弃(?!a)上面的前瞻,因为 db 可能不支持它。其他替代方案(删除了前瞻)是:

^([a-zA-Z0-9])\1+([a-zA-Z0-9])\2+?$ // will match aaaaaddd, aaaadd, bbbbdd, aaaaaaaa
^([a-zA-Z0-9])\1+([b-zB-Z0-9])\2+?$ // will match aaaaaddd but not aaaaaaaa
^([a-zA-Z0-9])\1{4}([b-zB-Z0-9])\2{2}?$ // will match aaaaaddd but not aaaaadd
^a{5}([b-zB-Z0-9])\1{2}?$ // will match aaaaaddd but not bbbbbddd

这将找到一个字母数字,旁边有另一个相同的字母数字,n 次,然后是另一组。这将成为您需要的基础。注意\w不一定与 相同a-zA-Z0-9,但[b-zB-Z0-9]如果您不想a在第二组中,可能是您可以做的最好的事情。

编辑添加^$根据添加的注释强制整个字符串匹配,并根据可能的要求添加选项

于 2013-05-29T09:55:23.900 回答
0

在你的情况下,我根本不会做正则表达式。如果您尝试进行的比较与您的示例一样简单,那么我会做一个简单的喜欢。我假设您正在尝试在 SELECT 语句中进行这些比较?

 create table t1 (field1 varchar2(100));

 -- what you want
 insert into t1 values ('aaaaabbb');
 insert into t1 values ('aaaaaccc');
 insert into t1 values ('aaaaaddd');
 insert into t1 values ('aaaaafff');

 -- what you dont want
 insert into t1 values ('aaaaaabc');
 insert into t1 values ('aaaaadef');
 insert into t1 values ('aaaaafgj');

 -- Just do a simple like
 with regex 
 as
 (-- all the possibilities
  select 'aaaaa' || rpad(alphabet, 3 , alphabet) lookup
  from  (-- a through z
         select chr(96 + rownum) alphabet
         from   dba_objects
         where  rownum <= 26) 
  ) 
 select *
 from   t1
 where  exists (select *
                from regex
                where t1.field1 like '%' || regex.lookup || '%')

如果表中的一行匹配多个 regex.lookup,我执行了 EXISTS 而不是连接。不过只是一个想法。

于 2013-05-29T11:55:40.967 回答