动态设置工作表名称时出现以下错误。在设置之前有没有人有regexp验证名称?
答案 0 :(得分:4)
您可以使用该方法检查工作表名称是否有效
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;
}
答案 1 :(得分:1)
让我们匹配字符串的开头,然后是1到31个不在禁止列表中的东西,然后是字符串的结尾。要求至少一种方法我们拒绝空字符串:
^[^\/\\\?\*\[\]]{1,31}$
这个正则表达式至少会有一个细微差别:这将接受一系列空格,制表符和换行符,如果被认为是空白(可能是这样),这将是一个问题。
如果您从正则表达式中检查长度,那么您可以通过执行以下操作来检查空白:
^[^\/\\\?\*\[\]]*[^ \t\/\\\?\*\[\]][^\/\\\?\*\[\]]*$
这是如何工作的?如果我们将上面的类定义为WORKSHEET,那就是:
^[^WORKSHEET]*[^\sWORKSHEET][^WORKSHEET]*$
因此我们匹配一个或多个非禁止字符,然后是既不禁止也不禁用空格的字符,然后是零个或多个非禁止字符。关键是我们要求中间部分至少有一个非空白字符。
但我们已经失去了长度检查。在一个表达式中很难同时执行长度检查和正则表达式。为了计算,我们必须根据匹配n
次来表达事物,并且必须知道匹配的事物的长度为1.但是为了允许自由放置空格 - 只要它不是所有的空白 - 我们需要有一部分不一定是长度为1的匹配。
嗯,那不是真的。在这一点上,这开始成为一个非常糟糕的主意,但是:从此开始,进入违规行为! (仅用于教育目的)
我们可以指定可能为空的部分的*
,而不是使用0+30, 1+29, 2+28, ... 30+0
来指定每个部分的数量,并包括这三个部分加起来的所有可能方式。有多少种方法可用于两个数字加起来30?好吧,其中有30个。 ^[^WORKSHEET]{0}[^\sWORKSHEET][^WORKSHEET]{30}$
|^[^WORKSHEET]{1}[^\sWORKSHEET][^WORKSHEET]{29}$
|^[^WORKSHEET]{2}[^\sWORKSHEET][^WORKSHEET]{28}$
....
|^[^WORKSHEET]{30}[^\sWORKSHEET][^WORKSHEET]{0}$
:
{{1}}
显然,如果这是一个好主意,你会编写一个表达式而不是手动指定它(并且出错了)。但我认为我不需要告诉你这不是一个好主意。然而,这是我对你的问题的唯一答案。
虽然诚然没有回答你的问题,但我认为@HatSoft有正确的方法,直接和清楚地编码条件。毕竟,我现在感到满意的是,对你提出的问题的答案实际上并不是一件有用的事情。
答案 2 :(得分:1)
要使用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.这两项检查不是通过Regex完成的,为了简单起见并避免过度设计这个问题。
答案 3 :(得分: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;
}
答案 4 :(得分:0)
您可能要检查名称History
,因为这是Excel中的保留工作表名称。