String contains only a given set of characters

前端 未结 7 1459
执笔经年
执笔经年 2021-02-18 13:22

I need to know if a given string is a valid DateTime format string because the string may represent other things. I tried DateTime.ParseExact(somedate.ToString(format), format)

相关标签:
7条回答
  • 2021-02-18 13:45

    Thank you everyone. I 'upped' all of you and settled on a brute force implementation that doesn't use a Dictionary/HashSet and doesn't convert chars to strings:

    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;
    }
    
    0 讨论(0)
  • 2021-02-18 13:49

    Slightly shorted Dan Tao's version since string represents an implementation of IEnumerable&lt&char>

       [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");
          }
       }
    
    0 讨论(0)
  • 2021-02-18 13:50

    Something like

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

    if you're literally searching for those characters and not the numerical representation for a given date and time

    0 讨论(0)
  • 2021-02-18 13:54

    With .NET2, you need to roll your own check for this. For example, the following method uses a foreach to check:

    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;
    }
    

    If you had the option of using .NET 3.5 and LINQ, you could use Enumerable.Contains to work with characters directly, and Enumerable.All. This would simplify the above to:

    bool valid = format.All(c => "yYmMdDsShH".Contains(c));
    
    0 讨论(0)
  • 2021-02-18 13:55

    There's a new project, NLib, which can do this much faster:

    if (input.IndexOfNotAny(new char[] { 'y', 'm', 'd', 's', 'h' }, StringComparison.OrdinalIgnoreCase) < 0)
    {
        // Valid
    }
    
    0 讨论(0)
  • 2021-02-18 14:02

    Like this:

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

    The regex works like this:

    • ^ matches the beginning of the string
    • [...] matches any of the characters that appear in the brackets
    • + matches one or more characters that match the previous item
    • $ matches the end of the string

    Without the ^ and $ anchors, the regex will match any string that contains at least one valid character, because a regex can match any substring of the string use pass it. The ^ and $ anchors force it to match the entire string.

    0 讨论(0)
提交回复
热议问题