Строка содержит только данный набор символов

Я должен знать, является ли данная строка допустимой строкой формата DateTime, потому что строка может представить другие вещи. Я попробовал DateTime. ParseExact (somedate. ToString (формат), формат) размышление его блевало бы на недопустимом формате, но это не делает.

Таким образом, я хорош с простым тестированием, если строка содержит только "yYmMdDsShH" символы. Что-то как станд.:: строка find_first_not_of работала бы, но Система. Строка не имеет этого.

Я думал, что 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", или я могу добавить несколько символов разделителя в нее также, мое дело, что позволить или не позволить.

21
задан Tergiver 20 July 2010 в 19:20
поделиться

6 ответов

В .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));
36
ответ дан 29 November 2019 в 06:33
поделиться

Например, так:

static readonly Regex Validator = new Regex(@"^[yYmMdDsShH]+$");

public static bool IsValid(string str) {
    return Validator.IsMatch(str);
}

Regex работает следующим образом:

  • ^ соответствует началу строки
  • [...] соответствует любому из символов, которые находятся в скобках
  • + соответствует одному или нескольким символам, которые соответствуют предыдущему пункту
  • $ соответствует концу строки

Без якорей ^ и $, регекс будет соответствовать любой строке, которая содержит хотя бы один допустимый символ, потому что регекс может соответствовать любой подстроке строки, которую ему передают. Анкоры ^ и $ заставляют его соответствовать всей строке.

19
ответ дан 29 November 2019 в 06:33
поделиться

Я бы просто сделал следующее:

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 "(поскольку это включает символы" - ").

Точное определение того, каких персонажей вы хотите разрешить, - это ваше суждение.

4
ответ дан 29 November 2019 в 06:33
поделиться

Что-то вроде

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

если вы буквально ищете эти символы, а не числовое представление для данной даты и времени

3
ответ дан 29 November 2019 в 06:33
поделиться

Слегка укороченная версия Дэна Тао, поскольку строка представляет собой реализацию 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");
      }
   }
1
ответ дан 29 November 2019 в 06:33
поделиться

Всем спасибо. Я «поднял» всех вас и остановился на реализации грубой силы, которая не использует 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;
}
0
ответ дан 29 November 2019 в 06:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: