plsql - Regex: How to Implement Negative Lookbehind in PL/SQL -
how match strings begin loockup.
, end _id
not prefixed msg
? here below examples:
lookup.asset_id -> should match lookup.msg_id -> shouldn't match lookup.whateverelse_id -> should match
i know oracle not back upwards negative lookbehind (i.e. (?<!)
)... i've tried explicitly enumerate possibilities using alternation:
regexp_count('i_asset := lookup.asset_id;', 'lookup\.[^\(]+([^m]|m[^s]|ms[^g])_id') <> 0 dbms_output.put_line('match'); -- matches expected end if; regexp_count('i_msg := lookup.msg_id;', 'lookup\.[^\(]+([^m]|m[^s]|ms[^g])_id') <> 0 dbms_output.put_line('match'); -- shouldn’t match -- previous example... why? end if;
the sec regexp_count
look should't match... first one. missing something?
edit
in real utilize case, i've string contains pl/sql code might contains more 1 lookup.xxx_id
instances:
declare l_source_code varchar2(2048) := ' ... curry := lookup.curry_id(key_val => ''chf'', key_type => ''asset_iso''); asset : = lookup.asset_id(key_val => ''ubsn''); -- wrong since -- not specify key_type ... msg := lookup.msg_id(key_val => ''hello''); -- fine since msg_id -- not require key_type '; ... end;
i need determine whether there @ to the lowest degree 1 wrong lookup
, i.e. occurrences, except lookup.msg_id
, must specify key_type
parameter.
with lookup\.[^\(]+([^m]|m[^s]|ms[^g])_id
, asking check string
lookup.
denoted lookup\.
, followed @ to the lowest degree 1 character different (
denoted [^\(]+
, followed either -- ( | | )
one character different m
-- [^m]
, or two characters: m
plus no s
-- m[^s]
, or three characters: ms
, no g
-- ms[^g]
, and ending in _id
denoted _id
. so, lookup.msg_id
, first part matches obviously, sec consumes ms
, , leaves g
first alternative of third.
this fixed patching 3rd part 3 characters long lookup\.[^\(]+([^m]..|m[^s.]|ms[^g])_id
. this, however, fail everything, part between lookup.
, _id
not @ to the lowest degree 4 characters long:
with input (s, r) ( select 'lookup.asset_id', 'should match' dual union select 'lookup.msg_id', 'shouldn''t match' dual union select 'lookup.whateverelse_id', 'should match' dual union select 'lookup.a_id', 'should match' dual union select 'lookup.ab_id', 'should match' dual union select 'lookup.abc_id', 'should match' dual ) select r, s, instr(s, 'lookup.msg_id') has_msg, regexp_count(s , 'lookup\.[^\(]+([^m]..|m[^s]|ms[^g])_id') matched input ; | r | s | has_msg | matched | |-----------------|------------------------|---------|---------| | should match | lookup.asset_id | 0 | 1 | | shouldn't match | lookup.msg_id | 1 | 0 | | should match | lookup.whateverelse_id | 0 | 1 | | should match | lookup.a_id | 0 | 0 | | should match | lookup.ab_id | 0 | 0 | | should match | lookup.abc_id | 0 | 0 |
if have create sure, there no msg
in position in question, might want go (instr(s, 'lookup.msg_id') = 0) , regexp_count(s, 'lookup\.[^\(]+_id') <> 0
for code clarity regexp_instr(s, 'lookup\.[^\(]+_id') > 0
might preferable…
@j3d comment if farther detail required.
regex plsql negative-lookbehind
No comments:
Post a Comment