1

Does anyone know of an algorithm (or external library) that I could call to convert an arbitrary string (i.e. outside my control) to be CLS compliant?

I am generating a dynamic RDLC (Client Report Definition) for an ASP.Net Report Viewer control and some of the field names need to be based on strings entered by the user.

Unfortunately I have little control over the entry of the field names by the client (through a 3rd party CMS). But I am quite flexible around substitutions required to create the compliant string.

I have a reactive hack algorithm for now along the lines of:

public static string FormatForDynamicRdlc(this string s)
{
    //We need to change this string to be CLS compliant.
    return s.Replace(Environment.NewLine, string.Empty)
        .Replace("\t", string.Empty)
        .Replace(",", string.Empty)
        .Replace("-", "_")
        .Replace(" ", "_");
}

But I would love something more comprehensive. Any ideas?

NOTE: If it is of any help, the algorithm I am using to create the dynamic RDLC is based on the BuildRDLC method found here: http://csharpshooter.blogspot.com/2007/08/revised-dynamic-rdlc-generation.html

Brian Hinchey
  • 3,601
  • 1
  • 39
  • 36

2 Answers2

4

Here's the algorithm I use to create C/C++ identifiers from arbitrary strings (translated to C#):

    static void Main(string[] args)
    {
        string input = "9\ttotally no @ # way!!!!";
        string safe = string.Concat("_", Regex.Replace(input, "[^a-z0-9_]+", "_"));
        Console.WriteLine(safe);
    }

The leading underscore is unnecessary if the first character of the regex result is not numeric.

David Gladfelter
  • 4,175
  • 2
  • 25
  • 25
  • Nice one! What can't regular expressions do :) – Brian Hinchey Jun 09 '10 at 23:55
  • 1
    I think the leading underscore is not allowed for a CLS-compliant name. See http://stackoverflow.com/a/1195061/1086134. Also beware that if you apply the algorithm above to a collection of strings, you may end up with a non-unique set of names. – Martin_W Oct 18 '13 at 19:19
  • @Martin_ATS You are right. How to get an unique set of names? Appending to the name a GUID string generated at runtime with 'Guid.NewGuid().ToString()' solves it, but it makes the name too long to be practical in some cases. – Emanuele Sabetta Nov 25 '16 at 16:34
  • The full line of code: string unique = safe + Guid.NewGuid().ToString("N"); – Emanuele Sabetta Nov 25 '16 at 17:24
0

Here is a regex which I found could be useful for splitting CLS-compliant string part and non-CLS-compliant string part. Below implementation in C#:

string strRegex = @"^(?<nonCLSCompliantPart>[^A-Za-z]*)(?<CLSCompliantPart>.*)";
Regex myRegex = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
string strTargetString = @"                            _aaaaaa[5]RoundingHeader";

foreach (Match myMatch in myRegex.Matches(strTargetString))
{
  if (myMatch.Success)
  {
    // Add your code here
  }
}
Dima M
  • 1
  • 1