Home » SQL & PL/SQL » SQL & PL/SQL » Help with REGEXP (Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 )
Help with REGEXP [message #631498] Wed, 14 January 2015 04:37 Go to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

In a script file I have some commented out line as below
select col1,col2, /*some text 1 */col3,/*some text 2*/col4
from mytable


Now I want to remove this commented out lines by using REGEXP function. Please help me.

Based on these scripts I create view dynamically in each month.

Thanks in advance.
Re: Help with REGEXP [message #631500 is a reply to message #631498] Wed, 14 January 2015 04:47 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

What should be the final result?

Re: Help with REGEXP [message #631501 is a reply to message #631500] Wed, 14 January 2015 04:51 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Final result should be
select col1,col2, col3,col4
from mytable
Re: Help with REGEXP [message #631506 is a reply to message #631501] Wed, 14 January 2015 05:02 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

SQL> with
  2    data as (
  3      select 'select col1,col2, /*some text 1 */col3,/*some text 2*/col4
  4  from mytable' v
  5      from dual
  6    )
  7  select regexp_replace(v, '/\*[^(*/)]*\*/') v
  8  from data
  9  /
V
----------------------------------------
select col1,col2, col3,col4
from mytable

Re: Help with REGEXP [message #631529 is a reply to message #631506] Wed, 14 January 2015 12:19 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3312
Registered: January 2010
Location: Connecticut, USA
Senior Member
You can't group inside brackets, so [^(*/)] means not (, not *, not / not ):

SQL> with
  2    data as (
  3      select 'select col1,col2, /*some (text) 1 */col3,/*some text 2*/col4
  4  from mytable' v
  5      from dual
  6    )
  7  select regexp_replace(v, '/\*[^(*/)]*\*/') v
  8  from data
  9  /

V
----------------------------------------------------------
select col1,col2, /*some (text) 1 */col3,col4
from mytable


All we need is non-gready .*:

with
  data as (
    select 'select col1,col2, /*some (text) 1 */col3,/*some text 2*/col4
from mytable' v
    from dual
  )
select regexp_replace(v, '/\*.*?\*/') v
from data
/

V
----------------------------------------
select col1,col2, col3,col4
from mytable


SQL> 


SY.
Re: Help with REGEXP [message #631530 is a reply to message #631529] Wed, 14 January 2015 12:28 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

Yes, thanks, I found my query very doubtful but did not have time to investigate, and also couldn't find yours as I didn't know "?" is a non-greedy modifier, I thought it was just indicating an optional part of the pattern.
Nice to know, and not just for Oracle.

Re: Help with REGEXP [message #631540 is a reply to message #631506] Wed, 14 January 2015 22:05 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Thanks All

But if there is line break within comments. It is not working. Could it be resolved?

Below SQL which has line break within '/* some text */' is not working.

"select col1,col2, /*some  
                                   (text) 1 */col3,col4
from mytable"


Please help.

Re: Help with REGEXP [message #631542 is a reply to message #631540] Thu, 15 January 2015 00:28 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

And did you try to make it work?

Re: Help with REGEXP [message #631546 is a reply to message #631542] Thu, 15 January 2015 01:46 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Yes I tried.

If there is line break it was not working.
To resolve this first I have replaced the CHR(10) with the text ' linebreak ', then applied your logic with REGEXP_REPLACE function and then again replaced the ' linebreak ' with CHR(10).
Below is my PL/SQL block.
Declare
 CURSOR cur_clob is
   select pkvr_period, var_part
   from pkv_ratio_calc_vw_definition
   where pkvr_period > '01-aug-2015';
   l_var_part CLOB;
begin
  for i in cur_clob loop
     l_var_part := replace(i.var_part,chr(10),' linebreak ');
     
     while instr(l_var_part,'/*') <> 0 or instr(l_var_part,'*/') <>0 loop
       l_var_part :=regexp_replace(l_var_part,'/\*.*?\*/');
     end loop;
     update pkv_ratio_calc_vw_definition
     set var_part = replace(l_var_part,' linebreak ',chr(10))
     where pkvr_period = i.pkvr_period;
     commit;

  end loop;
end;  
Re: Help with REGEXP [message #631547 is a reply to message #631546] Thu, 15 January 2015 02:17 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

I mean what did you try to make the regexp works?

Re: Help with REGEXP [message #631548 is a reply to message #631547] Thu, 15 January 2015 02:27 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

Hints:
1) you have nothing to change in the regexp pattern
2) read REGPEXP_REPLACE optional parameters and REGEXP_COUNT for a detailed explanation of the last one.

[Updated on: Thu, 15 January 2015 02:29]

Report message to a moderator

Re: Help with REGEXP [message #631557 is a reply to message #631548] Thu, 15 January 2015 05:05 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Now I have resolved it as below:

Declare
 CURSOR cur_clob is
   select pkvr_period, var_part
   from pkv_ratio_calc_vw_definition
   where pkvr_period = '01-sep-2015';
   l_var_part CLOB;
begin
  
  for i in cur_clob loop
     dbms_output.put_line('test');
     l_var_part := i.var_part;     
     while instr(l_var_part,'/*') <> 0 or instr(l_var_part,'*/') <>0 loop
       l_var_part :=regexp_replace(regexp_replace(regexp_replace(l_var_part,chr(10),' linebreak '),'/\*.*?\*/'),' linebreak ',chr(10));
     end loop;     
     dbms_output.put_line(substr(l_var_part,1,32000));
  end loop;
  
End; 


Is there any better way? Here REGEXP is nested thrice. I want to improve it.
Re: Help with REGEXP [message #631558 is a reply to message #631557] Thu, 15 January 2015 05:42 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

As I said, you can do it with the first query just adding optional parameters.
If you were not so reluctant to read the documentation you'd already have the query, you'd have it in less than 5 minutes.
Too bad.
Good luck with your PL/SQL sh...


Re: Help with REGEXP [message #631576 is a reply to message #631557] Thu, 15 January 2015 08:54 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3312
Registered: January 2010
Location: Connecticut, USA
Senior Member
mokarem wrote on Thu, 15 January 2015 06:05
Is there any better way? Here REGEXP is nested thrice. I want to improve it.


Yes there is - scrap your code. Use my solution. Add proper match_param value. Read about match_param in REGEXP_COUNT.

SY.
Re: Help with REGEXP [message #631582 is a reply to message #631576] Thu, 15 January 2015 09:02 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

Hope he will able to read it when this is you who tell him. Smile

Re: Help with REGEXP [message #631604 is a reply to message #631582] Thu, 15 January 2015 21:36 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

If I use the match_param, it gives the result null:

with
  data as (
    select 'select col1,col2, /*some 
            (text) 1 */col3,/*some text 2*/col4
from mytable' v
    from dual
  )
select regexp_replace(v,'/\*.*?\*/','','','','m') v
from data
/
Re: Help with REGEXP [message #631607 is a reply to message #631604] Fri, 16 January 2015 00:51 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

And why did you use '' for the other parameters?

Re: Help with REGEXP [message #631610 is a reply to message #631607] Fri, 16 January 2015 05:05 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3312
Registered: January 2010
Location: Connecticut, USA
Senior Member
It will not work even after fixing '' - OP is using wrong match_param.

SY.
Re: Help with REGEXP [message #631611 is a reply to message #631607] Fri, 16 January 2015 05:13 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

I got the below syntax:

REGEXP_REPLACE
(sourcestr, pattern [,replacestr [, position [, occurrence [, options]]]])

For my SQL, 'Position' should from the beginning of source text. 'Occurrence' means number of matching pattern. For my SQL it is not fixed.

Notice in below SQL I have given 'n' for 'Options' parameter which gives me the expected result.
For 'Occurrence' param I have give 0 from my assumption. Is 0 means unlimited for this param?


with
  data as (
    select 'select col1,col2, /*some 
            (text) 1 */col3,/*some text 2*/col4, /*some
                text*/col5, /*some % text*/col6
from mytable' v
    from dual
  )
select regexp_replace(v,'/\*.*?\*/','',1,0,'n') v
from data
/

v
---------------------
select col1,col2, col3,col4, col5, col6
from mytable



If I give 'm' for option parameters:

with
  data as (
    select 'select col1,col2, /*some 
            (text) 1 */col3,/*some text 2*/col4, /*some
                text*/col5, /*some % text*/col6
from mytable' v
    from dual
  )
select regexp_replace(v,'/\*.*?\*/','',1,0,'m') v
from data
/

V
-----------------------
select col1,col2, /*some 
            (text) 1 */col3,col4, /*some
                text*/col5, col6
from mytable


Now I am confused with the options parameter 'm' and 'n'.
In your links description about 'm' is "treats the source string as multiple lines".
Re: Help with REGEXP [message #631616 is a reply to message #631611] Fri, 16 January 2015 08:37 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3312
Registered: January 2010
Location: Connecticut, USA
Senior Member
Confused about what? You are trying to look for comments (/* followed by any number of any characters followed by */). By default dot doesn't match new line character, so pattern '/\*.*?\*/' will not match comment that spans multiple lines. Now you use match_param m which tells Oracle to apply regexp to each line, so how would it help finding /* xxx yyy */ if line is /* xxx and next line is yyy */ ? You WANT regexp to continue search in next line while searching for a pattern while m will force regexp to stop at the end of the line and start over, so m is out of the question. Issue we have, as I already noted, is dot doesn't match new line character. That's why we need match_param n. Then regexp will find /* then will start looking for a matching */ and will not stop at new line character. Hope it is clear now.

SY.

[Updated on: Fri, 16 January 2015 08:41]

Report message to a moderator

Re: Help with REGEXP [message #631627 is a reply to message #631610] Fri, 16 January 2015 10:02 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator
Solomon Yakobson wrote on Fri, 16 January 2015 12:05
It will not work even after fixing '' - OP is using wrong match_param.

SY.


Bad eyes, I read 'm' as 'n'.

Re: Help with REGEXP [message #631848 is a reply to message #631627] Tue, 20 January 2015 21:23 Go to previous messageGo to next message
mokarem
Messages: 109
Registered: November 2013
Location: Dhaka
Senior Member

Many Thanks for your detail explanation about option parameter's value 'm' and 'n'.

Now if I ommit '?' from the pattern:

with
  data as (
    select 'select col1,col2, /*some 
            (text) 1 */col3,/*some text 2*/col4, /*some
                text*/col5, /*some % text*/col6
from mytable' v
    from dual
  )
select regexp_replace(v,'/\*.*\*/','',1,0,'n') v
from data

V
=========================
select col1,col2, col6
from mytable



Would you please explain the purpose of '?' as you have explained the 'm'/'n' in detail?

I have gone through some links and found that '?' is a quantifier character and 'Match 0 or 1 time'. This is not clear to me.
Re: Help with REGEXP [message #631860 is a reply to message #631848] Wed, 21 January 2015 00:37 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

From the documentation (SQL Reference, Annex D):

Quote:
*? Matches the preceding pattern element 0 or more times (nongreedy).


By default, Oracle searches the largest string which matches the pattern, so here the last "*/" after "/*".
"*?", in this case, modifies the search so that it searches the first "*/" after "/*" (non-greedy).

"?" without "*" means the preceding (sub)pattern is optional.
SQL> select regexp_substr('abcdef','aX?b') from dual;
RE
--
ab

Re: Help with REGEXP [message #631961 is a reply to message #631860] Thu, 22 January 2015 06:34 Go to previous messageGo to next message
m.abdulhaq
Messages: 254
Registered: April 2013
Location: Ajman
Senior Member
thanks Michel and Solomon for nice explanation , one small clarification
Non greedy means "it will not stop with first reported match and display the first match but continues to find maximum combinations in the given string"

As what i understand "*" and "+" are repetitions , * is like {0,} -- 0 or any number of times
where as '+' is {1,} -- one or more time.

Please give me an appropriate example of greediness to understand it more clearly.

Re: Help with REGEXP [message #631970 is a reply to message #631961] Thu, 22 January 2015 08:10 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

Quote:
Non greedy means "it will not stop with first reported match and display the first match but continues to find maximum combinations in the given string"


No this is greedy, non-greedy means it stops at the first occurrence; normal behaviour is to go until the last one to find the largest string that matches the pattern.

Quote:
Please give me an appropriate example of greediness to understand it more clearly


You give it in your last example: Oracle searches from /* until it find the last */.
With "?", in the previous example, it searches from /* until it find one */, and does it several times as this happens several times in your string.
Another example:
SQL> with data as (select 'Antonio Mohamed Abdulha Khan' v from dual)
  2  select v, regexp_substr(v,'A.* ') greedy, regexp_substr(v,'A.*? ') non_greedy
  3  from data
  4  /
V                            GREEDY                       NON_GREEDY
---------------------------- ---------------------------- ----------------------------
Antonio Mohamed Abdulha Khan Antonio Mohamed Abdulha      Antonio

icon14.gif  Re: Help with REGEXP [message #631997 is a reply to message #631970] Fri, 23 January 2015 01:08 Go to previous message
m.abdulhaq
Messages: 254
Registered: April 2013
Location: Ajman
Senior Member
Great Michael, thanks for wonderful example and explanation.I got it now.
Previous Topic: Query on pagination Query
Next Topic: Special character issues
Goto Forum:
  


Current Time: Wed Aug 26 12:09:53 CDT 2026