mqf090
mqf090

Reputation: 11

C# Regex: Find All Calls to Other Stored Procedures In Procedure File

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

Answers (2)

Francis Gagnon
Francis Gagnon

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

Joshua Honig
Joshua Honig

Reputation: 13215

Just use the start-of-line anchor ^. Also,

  • There's no need to include both call and CALL when you're already specifying IgnoreCase.
  • Assuming call must be the first token on a line, you can skip the lookbehind
  • You don't need to escape the period since it's already in a character class
  • You can give a name to the part that matches the proc name and fetch it using the Match.Groups property
string 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

Related Questions