【问题标题】:How to do a negative lookahead in oracle regexp_like(), '?!' isn't working如何在 oracle regexp_like(), '?!' 中进行负前瞻不工作
【发布时间】:2017-09-26 13:23:02
【问题描述】:

查询:

select 1 "val" from dual where regexp_like('ITEM HEIGHT','^(?!ICON).*HEIGHT$'); 

上面的查询没有返回我1。请告诉我如何使用 oracle regexp_like() 实现负前瞻。

注意:请不要建议对查询进行任何更改,我很想知道regexp_like() 接受的正确正则表达式用于否定前瞻。此外 [^] 似乎仅逐个字符否定而不是整个字符串。

【问题讨论】:

  • 不确定是不是你想要的,但如果你想否定值,试试这个:'a[^b]'
  • Oracle 正则表达式不支持前瞻。
  • 我怀疑如果我必须排除一个字符串而不是一个字符怎么办?
  • 不确定您是否在此期间了解了更多关于正则表达式的知识......在您的尝试中,插入符号实际上是字符串开头的锚点。由于未转义的括号是元字符,因此它后面的问号实际上是语法错误。甲骨文老大哥选择忽略这个错误——它只是忽略了问号。然后它继续匹配:它查找以'!ICON' 开头并包含多一个字符(换行符除外)和'HEIGHT' 的字符串。 什么都没有关于排除任何东西!

标签: oracle negative-lookahead regexp-like


【解决方案1】:

正如其他人所提到的,Oracle 正则表达式不直接支持零宽度断言。

在某些情况下,您可以将要检查的内容拆分为多个表达式。对于您提供的示例,您可以执行以下操作:

select 1 "val"
 from dual
where NOT regexp_like('ITEM HEIGHT','^ICON')
  and regexp_like('ITEM HEIGHT','HEIGHT$');

如果您确实需要在单个表达式中执行此操作,您可以使用字符类的交替来一次检查一个字母,如下所示:

select 1 "val"
 from dual
where regexp_like('ITEM HEIGHT','^([^I]|I[^C]|IC[^O]|ICO[^N]).*HEIGHT$');

这个表达式的第一部分基本上是检查:

  • 第一个字符不是“我”
  • 或第一个字符是“I”,但第二个字符不是“C”
  • 或前两个字符是“IC”,但第三个字符不是“O”
  • 或者前三个字符是“ICO”,但第四个字符不是“N”

显然这种方法很快就会变得很麻烦,但在某些情况下它仍然有用。

【讨论】:

    【解决方案2】:

    Oracle 不支持正则表达式中的前瞻 - 相反,您可以检查下一个字符是否不是您要排除的字符:

    select 1 "val"
    from   dual
    where  regexp_like('ac','a([^b]|$)'); 
    

    【讨论】:

    • [^] 仅用于否定单个字符。如果我想否定一个字符串怎么办? select 1 "val" from dual where regexp_like('ICON HEIGHT','^([^ICON].*HEIGHT)');不符合我否定“ICON HEIGHT”的目的,因为它逐个字符而不是单个字符串。有什么办法解决这个问题?
    • select 1 "val" from dual where regexp_like('IA HEIGHT','^([^ICON].*HEIGHT)');应该返回我 1 但它不会因为 ^ 只否定一个字符。
    猜你喜欢
    • 2022-01-12
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多