views:

46

answers:

2

I have the following sample text and I want to replace '[core].' with something else but I only want to replace it when it is not between text markers ' (SQL):

PRINT 'The result of [core].[dbo].[FunctionX]' + [core].[dbo].[FunctionX] + '.'

EXECUTE [core].[dbo].[FunctionX]

The Result shoud be:

PRINT 'The result of [core].[dbo].[FunctionX]' + [extended].[dbo].[FunctionX] + '.'

EXECUTE [extended].[dbo].[FunctionX]

I hope someone can understand this. Can this be solved by a regular expression?

With RegLove

Kevin

A: 

Not in a single step, and not in an ordinary text editor. If your SQL is syntactically valid, you can do something like this:

First, you remove every string from the SQL and replace with placeholders. Then you do your replace of [core] with something else. Then you restore the text in the placeholders from step one:

  • Find all occurrences of '(?:''|[^'])+' with 'n', where n is an index number (the number of the match). Store the matches in an array with the same number as n. This will remove all SQL strings from the input and exchange them for harmless replacements without invalidating the SQL itself.
  • Do your replace of [core]. No regex required, normal search-and-replace is enough here.
  • Iterate the array, replacing the placeholder '1' with the first array item, '2' with the second, up to n. Now you have restored the original strings.

The regex, explained:

'          # a single quote
(?:        # begin non-capturing group
  ''|[^']  #   either two single quotes, or anything but a single quote
)+         # end group, repeat at least once
'          # a single quote

JavaScript this would look something like this:

var sql = 'your long SQL code';
var str = [];

// step 1 - remove everything that looks like an SQL string
var newSql = sql.replace(/'(?:''|[^'])+'/g, function(m) { 
  str.push(m);
  return "'"+(str.length-1)+"'";
});

// step 2 - actual replacement (JavaScript replace is regex-only)
newSql = newSql.replace(/\[core\]/g, "[new-core]");

// step 3 - restore all original strings
for (var i=0; i<str.length; i++){
  newSql = newSql.replace("'"+i+"'", str[i]);
}

// done.
Tomalak
A: 

Here is a solution (javascript):

str.replace(/('[^']*'.*)*\[core\]/g, "$1[extended]");

See it in action

galambalazs
"`PRINT 'The result of ''[core].[dbo].[FunctionX]''' + [core].[dbo].[FunctionX] + '.' EXECUTE [core].[dbo].[FunctionX]`"?
Tomalak
Have you bothered clicking on the link? Because I don't know where you copy your output from... There is a working example. Go and see it.
galambalazs
@galambalazs: Have you bothered trying with the string I posted? ;-) Because it doesn't work work this string.
Tomalak
that's not an input, that's invalid SQL. :)
galambalazs
No, it isn't. Look again. ;-)
Tomalak