开发者

Regular expression to find separator dots in formula

开发者 https://www.devze.com 2023-02-14 12:59 出处:网络
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:

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:

开发者_C百科'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.


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);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号