简体   繁体   中英

validate excel worksheet name

I'm getting the below error when setting the worksheet name dynamically. Does anyone has regexp to validate the name before setting it ?

  • The name that you type does not exceed 31 characters. The name does
  • not contain any of the following characters: : \\ / ? * [ or ]
  • You did not leave the name blank.

You can use the method to check if the sheet name is valid

private bool IsSheetNameValid(string sheetName)
{
    if (string.IsNullOrEmpty(sheetName))
    {
        return false;
    }

    if (sheetName.Length > 31)
    {
        return false;
    }

    char[] invalidChars = new char[] {':', '\\',  '/',  '?',  '*', '[', ']'};
    if (invalidChars.Any(sheetName.Contains))
    {
        return false;
    }

    return true;
}

Let's match the start of the string, then between 1 and 31 things that aren't on the forbidden list, then the end of the string. Requiring at least one means we refuse empty strings:

^[^\/\\\?\*\[\]]{1,31}$

There's at least one nuance that this regex will miss: this will accept a sequence of spaces, tabs and newlines, which will be a problem if that is considered to be blank (as it probably is).

If you take the length check out of the regex, then you can get the blankness check by doing something like:

^[^\/\\\?\*\[\]]*[^ \t\/\\\?\*\[\]][^\/\\\?\*\[\]]*$

How does that work? If we defined our class above as WORKSHEET, that would be:

^[^WORKSHEET]*[^\sWORKSHEET][^WORKSHEET]*$

So we match one or more non-forbidden characters, then a character that is neither forbidden nor whitespace, then zero or more non-forbidden characters. The key is that we demand at least one non-whitespace character in the middle section.

But we've lost the length check. It's hard to do both the length check and the regex in one expression. In order to count, we have to phrase things in terms of matching n times, and the things being matched have to be known to be of length 1. But in order to allow whitespace to be placed freely - as long as it's not all whitespace - we need to have a part of the match that is not necessarily of length 1.

Well, that's not quite true. At this point this starts to become a really bad idea, but nevertheless: onwards, into the breach! (for educational purposes only)

Instead of using * for the possibly-blank sections, we can specify the number we expect of each, and include all the possible ways for those three sections to add up to 31. How many ways are there for two numbers to add up to 30? Well, there's 30 of them. 0+30, 1+29, 2+28, ... 30+0 :

 ^[^WORKSHEET]{0}[^\sWORKSHEET][^WORKSHEET]{30}$
|^[^WORKSHEET]{1}[^\sWORKSHEET][^WORKSHEET]{29}$
|^[^WORKSHEET]{2}[^\sWORKSHEET][^WORKSHEET]{28}$
   ....
|^[^WORKSHEET]{30}[^\sWORKSHEET][^WORKSHEET]{0}$

Obviously if this was a good idea, you'd write a program that expression rather than specifying it all by hand (and getting something wrong). But I don't think I need to tell you it's not a good idea. It is, however, the only answer I have to your question.

While admittedly not actually answering your question, I think @HatSoft has the right approach, encoding the conditions directly and clearly. After all, I'm now satisfied that an answer to your question as asked is not actually a helpful thing.

To do worksheet validation for those specified invalid characters using Regex, you can use something like this:

string wsName = @"worksheetName"; //verbatim string to take special characters literally
Match m = Regex.Match(wsName, @"[\[/\?\]\*]");
bool nameIsValid = (m.Success || (string.IsNullOrEmpty(wsName)) || (wsName.Length > 31)) ? false : true;

This also includes a check to see if the worksheet name is null or empty, or if it's greater than 31. Those two checks aren't done via Regex for the sake of simplicity and to avoid over engineering this problem.

Something like that?

    public string validate(string name)
    {
        foreach (char c in Path.GetInvalidFileNameChars())
            name = name.Replace(c.ToString(), "");

        if (name.Length > 31)
            name = name.Substring(0, 31);

        return name;
    }

您可能需要检查名称History因为这是Excel中的保留工作表名称。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM