REGEX - How to capture blocks of CASE WHEN ... END

Asked

Viewed 111 times

3

Good morning, you guys.

I’m trying to make a regex to capture blocks of CASE WHEN ... END. So that string:

iduser + CaSe  WhEn ("end") = 0 THEN 'CASE WHEN' ELSE '  END ' END + sum(iduser ) + CASE  WHEN LANGUAGE = 3 THEN 4 ELSE 5 END

The blocks are captured:

CaSe  WhEn ("end") = 0 THEN 'CASE WHEN' ELSE 'END' END
CASE  WHEN LANGUAGE = 3 THEN 4 ELSE 5 END

What I get so far, was the result of a regex that I had done with a lot of sweat to catch string between brackets, it’s like this:

(CASE\\s*WHEN)([^)]+)(END)

But there are some problems:

  • ([^)]+) -> This part doesn’t make sense to me, but without it, no works;
  • I don’t want regex to capture blocks in quotes (simple or doubles).
  • ([^)]+) -> Besides not making sense, it makes string with parentheses not work.

EDIT

The regex is like this now, I managed to evolve a little:

(?i)(CASE\s*WHEN)(\s*.*)(END)

Now you no longer have the meaningless parenthesis and you are case insensitive. But, you are still not ignoring the quotation marks. And this modification has stopped taking all the blocks and is bringing them all together into one.

Thanks in advance!

  • Can be with Java or has to be with regex even?

  • 1

    It could be Java. But I would love to use regex in this solution.

  • 1

    could post your code with the quotes that are being ignored ?

  • Ex: CASE WHEN LANGUAGE = 0 THEN 'end' ELSE 'case when' END. regex must ignore the terms between single and double quotes.

  • Edit the question and put the string "true".

  • As well string "true"?

  • Example string has no quotation mark

  • Places the case tb variations

  • I edited. But this problem is written in the body of the question. It is important to read everything before, to understand the problem as a whole.

  • There is even a solution with regex, but there are 2 points: it uses features that Java does not support, and I think it is not the right tool for this problem. Maybe the solution is to use something like antlr, for example

Show 5 more comments

1 answer

0

The main problem is the "end" as it would be the end delimiter. And as you have "end" in the middle of the string it is not possible to do simply

(?i)(CASE\s+WHEN.*?END)

for the capture becomes incorrect.

For this we have to analyze what this "end" of the medium has different from the end, which is simple to quote.

Final solution

(?i)(CASE\s+WHEN.*?(?<!['"])END)

Explanation

  • (?i) - makes the search case insencitive.
  • CASE\s+WHEN seek the sentence CASE WHEN with at least one space.
  • .*? - captures everything, but tries as little as possible. Greedy operator
  • (?<!['"]) - is a Negative-Lookahead which ascertains the nature prior to END, and this can not be quote simlples or double.
  • END - Literal Search for END.

See functioned

  • William, thank you very much. But it didn’t work so well. Your solution only works if the 'end' in quotes is alone. If you put a space ' end' no longer works. By studying the operators, I was able to reach this solution, which works worse than yours: (? i)(CASE sWHEN)( s.*?[^'"])(END)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.