Oracle regexp_substr找到“\”,而不是“00”然后找到[0-9a-fA-F] {2}

时间:2018-03-07 06:56:58

标签: regex oracle

在值列表中,表示为\ nnnn,其中n是十六进制数字,我希望找到任何不以\ 00开头的事件并返回“\”和所有4位数

ex:\ 004e \ 2029 \ 00a3 - > \ 2029

据我所知:

select regexp_substr('\004e\2029\00a3', '\\^00[0-9A-Fa-f]{2}') from dual -- returns null

select regexp_substr('\004e\2029\00a3', '\\[^0]{2}[0-9A-Fa-f]{2}') from dual -- returns null, but would match \2129, both leading chars not "0"

我应该用“|”创建两次整个正则表达式并在第一个位置首先检查^ 0,然后在第二个位置检查^ 0?

这有效,但它不是非常无效吗?

'\\([^0][0-9A-Fa-f]{3}|[0-9A-Fa-f][^0][0-9A-Fa-f]{2})'

你有一个整洁的解决方案吗?

3 个答案:

答案 0 :(得分:2)

也许是这样的 - 如果事先知道输入字符串是四位数转义十六进制值的所有连接。

with 
  test_data as (
    select 101 as id, '\004e\2029\00a3' as str from dual union all
    select 103      , '\23ab\687a\0032'        from dual
  )
select id, level as ord,
       regexp_substr(str, '\\(.[^0]|[^0].)..', 1, level) as token
from   test_data
connect by level <= regexp_count(str, '\\(.[^0]|[^0].)..')
       and prior id = id
       and prior sys_guid() is not null
;


        ID        ORD  TOKEN         
----------  ---------  ---------------
       101          1  \2029          
       103          1  \23ab          
       103          2  \687a 

答案 1 :(得分:1)

这是一个选项:

SQL> with test (col) as
  2    (select '\004e\2029\00a3' from dual union
  3     select '\23ab\687a\0032' from dual
  4    )
  5  select '\' || regexp_substr(col, '[^\]+', 1, column_value) result
  6  from test,
  7       table(cast(multiset(select level from dual
  8                           connect by level <= regexp_count(col, '\\')
  9                          ) as sys.odcinumberlist))
 10  where substr(regexp_substr(col, '[^\]+', 1, column_value), 1, 2) <> '00';

RESULT
----------------
\2029
\23ab
\687a

答案 2 :(得分:0)

感谢您的意见和建议。我的工作正则表达式现在在我的机器中是一个幽灵,虽然我不确定它,但我确定它不是太昂贵,或者我可以优化它。