1

I have never used RegEx before, but a need for it arose today.

I need to see whether or not a string passed into my function is a valid Enum member name. Off the top of my head, this means that it cannot contain symbols (other than '_') and cannot start with a letter. Now I can google around and figure that out myself, but I wasn't too sure if those 2 rules were the only rules for enum member names - couldn't find anything online about it.

edit: To add some information... I am writing an editor plug in for unity3d. The user can populate a string list and the script will generate a c# file with those strings as members of the enum. The user can then reference the enum values through the code. The enum generated is basically a list of id's that the user specifies, so in code he can type IdEnum.SomeUserDefinedMember

Prodigga
  • 1,457
  • 1
  • 22
  • 37
  • 3
    Do you want to confirm whether it's valid *as* a member name? Or that it *is* a member? – Bobson May 20 '13 at 14:04
  • 4
    The C# Language Specification will give you the valid format for identifiers. See http://msdn.microsoft.com/en-us/library/vstudio/ms228593.aspx. In particular, see section B.1.6. It's unlikely that you can do this with just a regular expression, because you have to filter out keywords. – Jim Mischel May 20 '13 at 14:08
  • @JimMischel, I think you have the answer there. It would be possible to add in the list of C# keywords to the RegEx, but it would be ugly and error-prone. With some insight into the OP problem, perhaps we can find a better way. – Michael Sallmen May 20 '13 at 14:32
  • You have a typo. Enums can start with letters, they can't start with numbers. – gunr2171 May 20 '13 at 14:46
  • 1
    @JimMischel, No need to filter out keywords. They are perfectly legal enum values. Just need to start with @ when defining them. – Joel Rondeau May 20 '13 at 15:01
  • @JoelRondeau: So the string `explicit`, a keyword, is not a valid enum. The string `@explicit` is valid. But it's not a keyword. – Jim Mischel May 20 '13 at 15:06
  • @JimMischel, Yes and no. If I define an enum with a value of `@explicit`, and convert it to a string, the string is `explicit`, not `@explicit`. If I do an `Enum.TryParse()` on the string `explicit`, it is correctly parsed as the value that I defined with `@explicit`. – Joel Rondeau May 20 '13 at 15:14
  • @JoelRondeau: Got it. Thanks. Interesting. To refer to it in code, you would need `MyEnum.@explicit`, but to parse it from a string at runtime you don't need the `@`. – Jim Mischel May 20 '13 at 15:29
  • To add some information... I am writing an editor plug in for unity3d. The user can populate a string list and the script will generate a c# file with those strings as members of the enum. The user can then reference the enum values through the code. The enum generated is basically a list of id's that the user specifies, so in code he can type IdEnum.SomeUserDefinedMember. – Prodigga May 21 '13 at 09:35
  • Duplicate values can be filtered out after all the strings have been checked – Prodigga May 21 '13 at 09:39

3 Answers3

3

this regex should ensure valid name for enum value

^[a-zA-Z_][a-zA-Z_0-9]*
maxlego
  • 4,864
  • 3
  • 31
  • 38
  • 1
    No, it won't. See the language specification (linked in my comment to the OP). It allows Unicode characters and Unicode escape sequences, among other things. The specification also disallows keywords in enums. Your regular expression will identify only a small subset of the valid enums. – Jim Mischel May 20 '13 at 15:04
  • @JimMischel - While that's entirely true, it will identify the *most common* subset of valid enums. Depending on the OP's goal, that may be sufficient. – Bobson May 20 '13 at 18:49
  • "The *most common* subset of valid enums" *written by English speakers*, or perhaps by Western Europeans. That might indeed be sufficient for the OP's purpose. I wouldn't rely on it as a general solution, though. – Jim Mischel May 20 '13 at 18:52
  • @JimMischel - Valid point. That was very Anglocentric of me. – Bobson May 20 '13 at 21:58
2

(disclaimer: I never tested such solution, it's only an idea)

To handle all possible values, you may use the C# compiler directly to generate on the fly the enumeration, with your values. If the compilation fails, the enum's value is not valid.

You can try the code of this other SO question :

CodeTypeDeclaration type = new CodeTypeDeclaration("BugTracker");
type.IsEnum = true;

foreach (var valueName in new string[] { "Bugzilla", "Redmine" })
{
  // Creates the enum member
  CodeMemberField f = new CodeMemberField("BugTracker", valueName);


  type.Members.Add(f);
}

OldAnswser, before understanding your requirement :

I don't think using RegEx is the right way.

What you want to do can be coded like this :

enum MyEnum {
    Val1,
    Val2,
    Val3

}

class MyClass {
    void Foo(){
        string someInput = "Val2";

        MyEnum candidate;

        if(Enum.TryParse(someInput, out candidate)){
            // DO something with the enum
            DoSomething(candidate);
        }
        else{
            throw new VeryBadThingsHappened("someInput is not a valid MyEnum");
        }
    }
}
Community
  • 1
  • 1
Steve B
  • 36,818
  • 21
  • 101
  • 174
  • 1
    Though it wasn't asked that well, I'm pretty sure the OP is looking to ensure a specific string is a valid *member name* for C# (e.g. doesn't contain spaces). – Mike Perrenoud May 20 '13 at 14:10
  • 1
    I may have misunderstood the OP's goal. @Prodigga: please clarify what is your actual goal (*what* do you want to do, and not *how*). – Steve B May 20 '13 at 14:13
  • PPlease refer to the comment I added to the initial post! Sorry for the confusion :) – Prodigga May 21 '13 at 09:37
  • Regarding your comment, my solution does not apply. Sorry – Steve B May 21 '13 at 09:42
  • I read your new solution, and its an excellent idea! however, I couldn't get it to work. members where added even if they were invalid - adding a member called "new" didnt throw any errors. – Prodigga May 21 '13 at 10:09
  • Still no luck, I really want this solution to work too, because its so nice! heh. I wish it would spit something out when you provide an invalid name, but I am guessing that (under the hood) it doesnt use f.name as the actual name for that enum member? – Prodigga May 21 '13 at 10:27
  • I guess it's missing the actual compilation. Probably you are just building a code block with this code, but have to compile it to see if it's valid – Steve B May 21 '13 at 16:01
  • This is percisely how I did it. I wrote the code to a temporary file using what you put up above. I then compiled the file and checked to see if it returned any errors. If so, I popped up an invalid name dialogue and denied the user from adding those names to the enum in the real source file. – Prodigga May 22 '13 at 11:27
1

Just construct regex for every enumeration type like that:

Type enumeration = ...;
var regex = enumeration.Name + "\.(" + string.Join("|", Enum.GetNames(enumeration)) + ")";

It should match all values of given enum. You could also expand this to match more than one enum type.

ghord
  • 13,260
  • 6
  • 44
  • 69