Reputation: 11
I am trying to find all the names of the stored procedures called in a stored procedure file. A valid stored procedure call is:
call my_stored_procedure(param1, param2)
My strategy [based on my limited Regex knowledge] is to look for unique occurrences similar to: call my_stored_procedure(
Exceptions are those that have the double-dash "--" comments at the start of the line before a "call".
My idea is that once I get the string above, I can just find the actual stored procedure name by using "call" and "(" as delimiters which I do in some post-preocessing.
In a stored procedure file there can be many variations of this call. There can be multiple spaces and/or tabs in between each of the whole words.
call my_stored_procedure(param1, param2)
call my_stored_procedure(param1, param2)
call my_stored_procedure (param1, param2)
call my_stored_procedure (
param1, param2)
call my_stored_procedure ( param1, param2 )
-- call my_stored_procedure (param1, param2)
--call my_stored_procedure (param1, param2)
--call my_stored_procedure
-- jsmith call my_stored_procedure (param1, param2)
I'm using the ASP.Net Regex engine and so far this is what I have:
Regex rgxFindStoredProcedures = new Regex(@"(?<!.*--? *)(call|CALL)\s*([A-Za-z0-9-_\.]+)(\s*)\(",
RegexOptions.Multiline | RegexOptions.IgnoreCase);
Above Regex seems to work and I find all matches and excludes the first 3 commented out calls. However, it is including last commented call:
-- jsmith call my_stored_procedure (param1, param2)
Does any body have an idea how I can filter out this last commented out call? My thought is to put a condition inside of
(?<!.*--? * some_condition_here)
which drops the match if there are words after the -- not equal to "call" but I can't quite figure out how to frame the Regex for this condition.
Any help is greatly appreciated.
Upvotes: 1
Views: 481
Reputation: 3675
Here is a regex that should do what you want.
^(?<!--.*?)\s*call\s+[A-Za-z0-9-_\.]+\s*\(
It matches the first five calls in your sample text.
Upvotes: 0
Reputation: 13215
Just use the start-of-line anchor ^
. Also,
call
and CALL
when you're already specifying IgnoreCase
. call
must be the first token on a line, you can skip the lookbehindstring pattern = @"^\s*call\s*(?<ProcName>[A-Za-z0-9_.]+)(\s*)\(";
var rx = new Regex(pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);
foreach(var m in rx.Matches(yourInput))
Console.WriteLine(m.Groups["ProcName"].Value);
Upvotes: 3