Saturday, 15 June 2013

plsql - Regex: How to Implement Negative Lookbehind in PL/SQL -



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

starting 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