2

动态设置工作表名称时出现以下错误。有没有人在设置名称之前有正则表达式来验证名称?

  • 您键入的名称不超过 31 个字符。这个名字确实
  • 不包含以下任何字符: : \ / ? * [ 或者 ]
  • 您没有将名称留空。
4

5 回答 5

5

您可以使用该方法检查工作表名称是否有效

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;
}
于 2012-08-05T14:38:05.500 回答
2

让我们匹配字符串的开头,然后是 1 到 31 个不在禁止列表中的事物,然后是字符串的结尾。要求至少一个意味着我们拒绝空字符串:

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

这个正则表达式至少会遗漏一个细微差别:这将接受一系列空格、制表符和换行符,如果认为它是空白的(可能是这样),这将是一个问题。

如果您从正则表达式中取出长度检查,那么您可以通过执行以下操作来进行空白检查:

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

这是如何运作的?如果我们将上面的类定义为 WORKSHEET,那将是:

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

所以我们匹配一个或多个非禁止字符,然后是一个既不是禁止也不是空格的字符,然后是零个或多个非禁止字符。关键是我们要求中间部分至少有一个非空白字符。

但是我们丢失了长度检查。很难在一个表达式中同时进行长度检查和正则表达式。为了计算,我们必须根据匹配n时间来表述事物,并且必须知道被匹配的事物的长度为 1。但是为了允许自由放置空格 - 只要它不是全是空格 -我们需要匹配的一部分不一定长度为 1。

嗯,这并不完全正确。在这一点上,这开始成为一个非常糟糕的主意,但是:继续,进入突破口!(仅用于教育目的)

我们可以指定我们期望的每个部分的数量,而不是使用*可能为空的部分,并包括这三个部分加起来为 31 的所有可能方式。两个数字加起来为 30 有多少种方式?嗯,有30个。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}$

显然,如果这是一个好主意,您应该编写一个该表达式的程序,而不是手动指定它(并且出错)。但我不认为我需要告诉你这不是一个好主意。然而,这是我对你的问题的唯一答案。

虽然诚然没有真正回答你的问题,但我认为@HatSoft 有正确的方法,直接清晰地编码条件。毕竟,我现在很满意,按要求回答您的问题实际上并没有帮助。

于 2012-08-05T15:45:59.623 回答
2

要使用 Regex 对那些指定的无效字符进行工作表验证,您可以使用以下内容:

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;

这还包括检查工作表名称是否为空或空,或者是否大于 31。为了简单起见并避免过度设计此问题,这两个检查不是通过正则表达式完成的。

于 2012-08-05T15:48:59.097 回答
0

类似的东西?

    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;
    }
于 2012-08-05T14:43:38.557 回答
0

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

于 2018-11-30T15:17:19.343 回答