我需要知道给定的字符串是否是有效的DateTime格式字符串,因为字符串可能代表其他内容。我尝试了DateTime.ParseExact(somedate.ToString(format),format),认为它会在无效格式上进行barf,但事实并非如此。
所以我很擅长测试字符串是否只包含“yYmMdDsShH”字符。像std :: string.find_first_not_of这样的东西可行,但System.String没有这个。
我认为RegEx可能会做到这一点,但我对正则表达式非常弱。
请注意,Linq不适用于此版本(仅限.NET 2.0)。
更新
为了澄清,我需要知道给定的字符串是否代表日期时间格式,而不是像这样的其他内容:
if (input == "some special value")
... // it's a special case value
else if (Environment.GetEnvironmentVariable(input))
... // it's an environment variable name
else if (IsDateTimeFormatString(input))
... // it's a date time format string
else if (input.IndexOfAny(Path.GetInvalidPathChars()) < 0)
... // it's a file path
else
throw new Exception(); // Not a valid input
我可以将DateTime格式字符串限制为仅仅“yYmMdDsShH”,或者我也可以在其中添加一些分隔符,这取决于我允许或不允许的内容。
答案 0 :(得分:36)
使用.NET2,您需要为此进行自己的检查。例如,以下方法使用foreach进行检查:
bool FormatValid(string format)
{
string allowableLetters = "yYmMdDsShH";
foreach(char c in format)
{
// This is using String.Contains for .NET 2 compat.,
// hence the requirement for ToString()
if (!allowableLetters.Contains(c.ToString()))
return false;
}
return true;
}
如果您可以选择使用.NET 3.5和LINQ,则可以使用Enumerable.Contains直接处理字符和Enumerable.All。这将简化以上内容:
bool valid = format.All(c => "yYmMdDsShH".Contains(c));
答案 1 :(得分:16)
像这样:
static readonly Regex Validator = new Regex(@"^[yYmMdDsShH]+$");
public static bool IsValid(string str) {
return Validator.IsMatch(str);
}
正则表达式的工作原理如下:
^
匹配字符串的开头[...]
匹配括号中显示的任何字符+
匹配与上一项匹配的一个或多个字符$
匹配字符串的结尾如果没有^
和$
锚点,正则表达式将匹配包含至少一个有效字符的任何字符串,因为正则表达式可以匹配字符串的任何子字符串使用传递它。 ^
和$
锚点强制它匹配整个字符串。
答案 2 :(得分:4)
我只是这样做:
public static class DateTimeFormatHelper
{
// using a Dictionary<char, byte> instead of a HashSet<char>
// since you said you're using .NET 2.0
private static Dictionary<char, byte> _legalChars;
static DateTimeFormatHelper()
{
_legalChars = new Dictionary<char, byte>();
foreach (char legalChar in "yYmMdDsShH")
{
_legalChars.Add(legalChar, 0);
}
}
public static bool IsPossibleDateTimeFormat(string format)
{
if (string.IsNullOrEmpty(format))
return false; // or whatever makes sense to you
foreach (char c in format)
{
if (!_legalChars.ContainsKey(c))
return false;
}
return true;
}
}
当然,这可能是一个过于严格的定义,因为它排除了大多数人会认为有效格式的内容,例如“yyyy-MM-dd”(因为它包含“ - ”字符)。
确切地确定您希望允许的字符是您的判断。
答案 3 :(得分:3)
像
这样的东西Regex regex = new Regex("^(y|Y|m|M|d|D|s|S|h|H)+$");
if (regex.IsMatch('DateTime String'))
{
// 'valid'
}
如果你真的在搜索这些字符而不是给定日期和时间的数字表示
答案 4 :(得分:1)
Dan Tao的版本略有缩短,因为字符串表示IEnumerable&amp; lt&amp; char&gt;
的实现 [TestClass]
public class UnitTest1 {
private HashSet<char> _legalChars = new HashSet<char>("yYmMdDsShH".ToCharArray());
public bool IsPossibleDateTimeFormat(string format) {
if (string.IsNullOrEmpty(format))
return false; // or whatever makes sense to you
return !format.Except(_legalChars).Any();
}
[TestMethod]
public void TestMethod1() {
bool result = IsPossibleDateTimeFormat("yydD");
result = IsPossibleDateTimeFormat("abc");
}
}
答案 5 :(得分:0)
谢谢大家。我'恭喜'你们所有人,并坚持使用不使用Dictionary / HashSet并且不将字符转换为字符串的暴力实现:
private const string DateTimeFormatCharacters = "yYmMdDhHsS";
private static bool IsDateTimeFormatString(string input)
{
foreach (char c in input)
if (DateTimeFormatCharacters.IndexOf(c) < 0)
return false;
return true;
}
答案 6 :(得分:0)
有一个新项目NLib,可以更快地完成这项任务:
if (input.IndexOfNotAny(new char[] { 'y', 'm', 'd', 's', 'h' }, StringComparison.OrdinalIgnoreCase) < 0)
{
// Valid
}