8

I find an example at oracle forum site :

Input string : a, b, c (x, y, z), a, (xx, yy, zz), x,

WITH t AS (SELECT 'a, b, c (x, y, z), a, (xx, yy, zz), x,' col1 
         FROM dual)
SELECT t.col1
 , REGEXP_REPLACE(t.col1, '(\(.*?\))|,', '\1') new_col
FROM t

Output : a b c (x, y, z) a (xx, yy, zz) x

But i want to make opposite of that. Just remove this character , from inside () and remain outside.

Output : a, b, c (x y z), a, (xx yy zz), x,

3
  • how many , do you expect between the () ? Commented Jul 26, 2011 at 7:55
  • 1
    REGEXP_REPLACE in Oracle uses the flavor POSIX ERE which has no look around feature. This information is taken from here Commented Jul 26, 2011 at 8:21
  • 1
    To add to @bw_üezi's comment - I've confirmed lookarounds aren't supported in Oracle using REGEXP_REPLACE. Mandatory comment: it doesn't look like data that should be raw in the database - specially if you're going to query it. Are you sure you cannot normalize it? (I know you probably can't at this point...) Commented Jul 26, 2011 at 8:22

3 Answers 3

3

This will work for a constant length of arguments with in the brackets.

REGEXP_REPLACE(t.col1, '(\(.*?),(.*?),(.*?\))', '\1\2\3') new_col

update inspired by @Kobi's comment:
this regular expression removes the 1st, optional 2nd and optional 3rd , between ()
it can be extended up to 9 (I've a book stating \1 ... \500 should be possible but only \1 ... \9 worked)

REGEXP_REPLACE(t.col1, '\(([^,]*),([^,]*),?([^,]*),?([^,]*)\)', '(\1\2\3\4)') new_col
Sign up to request clarification or add additional context in comments.

3 Comments

You can use something like \(([^,]*?),([^,)]*?),?([^,)]*?)\), (\1\2\3) to support 2 or 3 elements, and can easily expand it to a reasonable maximum number of elements. Finding a general regex is tricky in this case...
how many , do you expect between the () ? infinite :)) therefore, this regular expression must be more general
@hamdi you can extend this regex shown here to run with 4 elements between brackets to support up to 9 elements. To deal with infinite number of elements SQL may not be the right tool. A more general regular expression can be achieved by 'look around' feature which is NOT supported by Oracle.
2

A little modified version of the regular expression you used:

REGEXP_REPLACE(column_name, '((\)|^).*?(\(|$))|,', '\1')

Comments

1

Not sure if REGEXP_REPLACE supports negative look aheads and look behinds, but if it does this would work: ,(?<!\)[^\(]*)(?![^\)]*\()

I tested with C#:

string s = "a, b, c (x, y, z), a, (xx, yy, zz), x,";

Console.WriteLine(Regex.Replace(s, @",(?<!\)[^\(]*)(?![^\)]*\()", ""));

1 Comment

REGEXP_REPLACE in Oracle uses the flavor POSIX ERE which has no look around feature. This information is taken from here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.