3

The C# expression library I am using will not directly support my table/field parameter syntax:

The following are table/field parameter names that are not directly supported:

TableName1.FieldName1
[TableName1].[FieldName1]
[Table Name 1].[Field Name 1]

It accepts alphanumeric parameters without spaces, or most characters enclosed within square brackets. I would like to use C# regular expressions to replace the dot separators and neighboring brackets to a different delimiter, so the results would be as follows:

[TableName1|FieldName1]
[TableName1|FieldName1]
[Table Name 1|Field Name 1]

I also need to skip any string literals within single quotes, like:

'TableName1.FieldName1'

And, of course, ignore any numeric literals like:

12345.6789

EDIT: Thank you for your feedback on improving my question. Hopefully it is clearer now.

polara
  • 4,862
  • 5
  • 24
  • 19
  • 2
    You don't give enough information. "Isolate" is a general and relative term and you can't pile on a specification by adding conditionals to an already obscure one. Be more specific with some background of usage. –  Mar 01 '11 at 02:02
  • I agree, I've no firm idea of what it is you want to achieve. Perhaps you could state what result you'd like from running the regex, and perhaps also what you wouldn't want to see as the result (sometimes that can be really helpful) – ian Mar 01 '11 at 04:00
  • Also, you should specify the regex engine you're using. Can there be constructs like `[Table.Name].[Field.Name]` where you only want to split on the middle dot? – Tim Pietzcker Mar 01 '11 at 07:53
  • @sln, @Iain: I updated my initial post to expand on my requirements.@Tim: – polara Mar 01 '11 at 15:38
  • @Tim Pietzcker: Using the C# regex engine. The only constructs I support are listed in my examples. – polara Mar 01 '11 at 15:39
  • I suppose those constructs are found in a larger context (i. e. not one construct per string/line, but mixed in with other text)? – Tim Pietzcker Mar 01 '11 at 17:47
  • @Tim Pietzcker: Yes, they are part of a formula, so you could have something like [Table Name 1].[Field Name 1]+100+[Table Name 2].[Field Name 2] in a single expression. – polara Mar 01 '11 at 21:10

1 Answers1

4

I've written a completely new answer, now that the problem is clarified:

You can do this in a single regex. It is quite bulletproof, I think, but as you can see, it's not exactly self-explanatory, which is why I've commented it liberally. Hope it makes sense.

You're lucky that .NET allows re-use of named capturing groups, otherwise you would have had to do this in several steps.

resultString = Regex.Replace(subjectString, 
    @"(?:             # Either match...
     (?<before>       #  (and capture into backref <before>)
      (?=\w*\p{L})    #  (as long as it contains at least one letter):
      \w+             #  one or more alphanumeric characters,
     )                #  (End of capturing group <before>).
     \.               #  then a literal dot,
     (?<after>        #  (now capture again, into backref <after>)
      (?=\w*\p{L})    #  (as long as it contains at least one letter):
      \w+             #  one or more alphanumeric characters.
     )                #  (End of capturing group <after>) and end of match.
    |                 # Or:
     \[               #  Match a literal [
     (?<before>       #  (now capture into backref <before>)
      [^\]]+          #  one or more characters except ]
     )                #  (End of capturing group <before>).
     \]\.\[           #  Match literal ].[
     (?<after>        #  (capture into backref <after>)
      [^\]]+          #  one or more characters except ]
     )                #  (End of capturing group <after>).
     \]               #  Match a literal ]
    )                 # End of alternation. The match is now finished, but
    (?=               # only if the rest of the line matches either...
     [^']*$           #  only non-quote characters
     |                # or
     [^']*'[^']*'     #  contains an even number of quote characters
     [^']*            #  plus any number of non-quote characters
     $                #  until the end of the line.
    )                 # End of the lookahead assertion.", 
    "[${before}|${after}]", RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • This is perfect, exactly what I needed. I really appreciate all of the comments that explain how it works. Hopefully this will be helpful for others trying to learn regex. Thanks for all your help Tim. – polara Mar 02 '11 at 18:24