String仅包含给定的一组字符

我需要知道给定的字符串是否是有效的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”,或者我也可以在其中添加一些分隔符,这取决于我允许或不允许的内容。

使用.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)); 

像这样:

 static readonly Regex Validator = new Regex(@"^[yYmMdDsShH]+$"); public static bool IsValid(string str) { return Validator.IsMatch(str); } 

正则表达式的工作方式如下:

  • ^匹配字符串的开头
  • [...]匹配括号中出现的任何字符
  • +匹配与前一项匹配的一个或多个字符
  • $匹配字符串的结尾

如果没有^$ anchors,正则表达式将匹配包含至少一个有效字符的任何字符串,因为正则表达式可以匹配字符串的任何子字符串使用传递它。 ^$ anchors强制它匹配整个字符串。

我只是这样做:

 public static class DateTimeFormatHelper { // using a Dictionary instead of a HashSet // since you said you're using .NET 2.0 private static Dictionary _legalChars; static DateTimeFormatHelper() { _legalChars = new Dictionary(); 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”(因为它包括“ – ”字符)。

准确确定您希望允许的字符是您的判断。

就像是

 Regex regex = new Regex("^(y|Y|m|M|d|D|s|S|h|H)+$"); if (regex.IsMatch('DateTime String')) { // 'valid' } 

如果你真的在搜索那些字符而不是给定日期和时间的数字表示

由于字符串代表IEnumerable&lt; char>的实现,因此Dan Tao的版本略有缩短

  [TestClass] public class UnitTest1 { private HashSet _legalChars = new HashSet("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"); } } 

谢谢大家。 我’恭喜’你们所有人并且决定使用不使用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; } 

有一个新项目, NLib ,它可以更快地做到这一点:

 if (input.IndexOfNotAny(new char[] { 'y', 'm', 'd', 's', 'h' }, StringComparison.OrdinalIgnoreCase) < 0) { // Valid }