Skip to content

Instantly share code, notes, and snippets.

@shane-js
Last active September 28, 2017 04:37
Show Gist options
  • Save shane-js/9582fe523c3ad76c9a4afa1e1144865e to your computer and use it in GitHub Desktop.
Save shane-js/9582fe523c3ad76c9a4afa1e1144865e to your computer and use it in GitHub Desktop.
C# Sql Identifier Parser
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace CSharpSqlIdentifierParser
{
public class CSharpSqlIdentifierParserClass
{
// Parses funky sql identifiers as strings back as their individual components which hopefully makes them easier to read
// Examples:
// database.schema.table -> string[] { "database", "schema", "table" }
// [database]]with[annoying]]name].schema.table -> string[] { "database]with[annoying]name", "schema", "table" }
// [[d]]]]]][].schema.table -> string[] { "[d]]][", "schema", "table" }
// \"\"\"\"\"\"\".schema.table -> string[] {"\"\"\"", "schema", "table"}
private static string[] SplitSqlIdentifier(string identifier)
{
var splitIdentifiers = new List<string>();
var initialIdentifierRegex = @"(?:\[).+[\[\]]|(?:^|\.)[^\.]+";
//Explained
// (?:\[) starts with open bracket
// .+ match one or more of any character
// [\[\]] match either open or closed bracket
//| or
//(?:^|\.) starts beginning of the string or with a period
//[^\.]+ has one or more of any character except period
var initialSplitIdentifiersMatches = Regex.Matches(identifier, initialIdentifierRegex).Cast<Match>().ToArray();
foreach(var match in initialSplitIdentifiersMatches)
{
var unsanitizedIdentifier = match.ToString();
//remove periods at beginning or end
if (unsanitizedIdentifier[0] == '.') { unsanitizedIdentifier = unsanitizedIdentifier.Remove(0, 1); };
if (unsanitizedIdentifier[unsanitizedIdentifier.Length - 1] == '.') { unsanitizedIdentifier = unsanitizedIdentifier.Remove(unsanitizedIdentifier.Length - 1, 1); };
///////////////////////////// BEGIN HANDLE SURROUNDINGS ////////////////////////////
//remove surrounding opened AND closed brackets
if (unsanitizedIdentifier[0] == '[' && unsanitizedIdentifier[unsanitizedIdentifier.Length - 1] == ']') {
unsanitizedIdentifier = unsanitizedIdentifier.Remove(0, 1);
unsanitizedIdentifier = unsanitizedIdentifier.Remove(unsanitizedIdentifier.Length - 1, 1);
};
//remove surrounding double quotes
if (unsanitizedIdentifier[0] == '"' && unsanitizedIdentifier[unsanitizedIdentifier.Length - 1] == '"')
{
unsanitizedIdentifier = unsanitizedIdentifier.Remove(0, 1);
unsanitizedIdentifier = unsanitizedIdentifier.Remove(unsanitizedIdentifier.Length - 1, 1);
};
///////////////////////////// END HANDLE SURROUNDINGS ////////////////////////////
///////////////////////////// BEGIN HANDLE LITERALS ////////////////////////////
unsanitizedIdentifier = unsanitizedIdentifier.Replace("\"\"", "\""); //replace literal double quotes
unsanitizedIdentifier = unsanitizedIdentifier.Replace("]]", "]"); //replace literal closing brackets
///////////////////////////// END HANDLE LITERALS ////////////////////////////
splitIdentifiers.Add(unsanitizedIdentifier);
}
return splitIdentifiers.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment