We use the RoundhousE migration tool in one of our more SQL oriented projects. I have stubble upon a very strange bug

A certain SQL function script (Sadly I cant supply the script because its the property of my customer) makes the Replace method of RegEx never return

The regex looks like this

(?<KEEP1>^(?:[\s\t])*(?:-{2}).*$)|(?<KEEP1>/{1}\*{1}[\S\s]*?\*{1}/{1})|(?<KEEP1>'{1}(?:[^']|\n[^'])*?'{1})|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s)|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>$)

The code line in RounhousE that never returns

string sql_statement_scrubbed = regex_replace.Replace(sql_to_run, match => evaluate_and_replace_batch_split_items(match, regex_replace));

The problem is not in the delegate evaluate_and_replace_batch_split_items its in the actual regex.Replace method, i've tried the regex in a simple regex tool and it also hangs. Maybe someone here that are a guru on RegEx can see what the problem is?

edit: If I remove the ' (Apostrophe) from this sql comment -- If no previous, don't report revised it works, but its not only that it must be a combination of other text in the script because that line works on its own

有帮助吗?

解决方案

Usually, when a regex takes forever to match (or, more likely, find out that it doesn't match) it's because of catastrophic backtracking. There are a few instances in your regex that might be prone to this, depending on what your input looks like. I have taken your regex and cleaned it up a little, removing lots of unnecessary quantifiers and alternations. This regex:

(?<KEEP1>^\s*--.*$)|(?<KEEP1>/\*[\S\s]*?\*/)|(?<KEEP1>'[^']*')|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s|$)

will match exactly the same as your old regex, but it's less complex and should be more stable. Please give it a try.

To handle escaped apostrophes within strings ('It\'s something else!') correctly, you would need to change the regex:

(?<KEEP1>^\s*--.*$)|(?<KEEP1>/\*[\S\s]*?\*/)|(?<KEEP1>'(?:\\.|[^'\\])*')|(?<KEEP1>\s)(?<BATCHSPLITTER>GO)(?<KEEP2>\s|$)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top