tags:

views:

38

answers:

4

I'm attempting to mangle a SQL query via regex. My goal is essentially grab what is between FROM and ORDER BY, if ORDER BY exists.

So, for example for the query: SELECT * FROM TableA WHERE ColumnA=42 ORDER BY ColumnB it should capture TableA WHERE ColumnA=42, and it should also capture if the ORDER BY expression isn't there.

The closest I've been able to come is SELECT (.*) FROM (.*)(?=(ORDER BY)) which fails without the ORDER BY.

Hopefully I'm missing something obvious. I've been hammering in Expresso for the past hour trying to get this.

A: 

You need to make the whole subexpression including the ORDER BY optional, by putting a ? after it:

SELECT (.*) FROM (.*?) (ORDER BY (.*))?$

You also need the pattern after the FROM to be a non-greedy match .*?, otherwise that would always consume the ORDER BY, and the final part would never match.

Andy Mortimer
This fails on the sample query listed in the question. It only captures the first word after the FROM.
Matt S
Ah, yes, I needed to anchor the end of the RE to make sure it picked up the whole line. Fixed.
Andy Mortimer
A: 

Just add an alteration to your regex:

SELECT (.*) FROM (.*)(?=(ORDER BY|\Z|$))

drewk
A: 

Could you just append "ORDER BY" to the string before applying the regex? It's a bit of a hack, but it ought to work.

Carl Manaster
The order by is already on the string. I'm looking to capture what's between the FROM and ORDER BY, if it exists
Matt S
But the question says, "it should also capture if the ORDER BY expression isn't there." By forcing it to be there, you can simplify the regex.
Carl Manaster
+1  A: 

I think you were looking for this :

^SELECT (.+) FROM (.+?)( ORDER BY (.+))?$

Note that I forced the start and end points of the string. This way the optional order by is going to be evaluated, and if it's not present, the rest of the code is going to be included in the second match group.

P.S. you can of course edit it as you want.. I put the last .+ in a group as well, so that you can easily access the order by params.. if you don't need it - you can remove them :P Same with the first one in the SELECT, but I guess you know that already :)

Artiom Chilaru
This worked with one small modification (moving the space between the second capture expression and the order by capture into the order by capture. Thank you very much
Matt S
You're very much welcome, and yes, you're right.. I kind of missed that one :DWill update the answer (if I can) with it )
Artiom Chilaru