Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字符串只包含一组给定的字符_C#_Regex - Fatal编程技术网

C# 字符串只包含一组给定的字符

C# 字符串只包含一组给定的字符,c#,regex,C#,Regex,我需要知道给定的字符串是否是有效的日期时间格式字符串,因为该字符串可能表示其他内容。我尝试了DateTime.ParseExact(somedate.ToString(format),format),认为它会吐出一个无效的格式,但它没有 因此,我擅长简单地测试字符串是否只包含“yymddssh”字符。类似std::string.find_first_not_of会起作用,但System.string没有这个功能 我原以为正则表达式可以做到这一点,但我对正则表达式的理解很弱 请注意,Linq不适用

我需要知道给定的字符串是否是有效的日期时间格式字符串,因为该字符串可能表示其他内容。我尝试了DateTime.ParseExact(somedate.ToString(format),format),认为它会吐出一个无效的格式,但它没有

因此,我擅长简单地测试字符串是否只包含“yymddssh”字符。类似std::string.find_first_not_of会起作用,但System.string没有这个功能

我原以为正则表达式可以做到这一点,但我对正则表达式的理解很弱

请注意,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
if(输入==“某些特殊值”)
... // 这是一个特例值
else if(Environment.GetEnvironmentVariable(输入))
... // 这是一个环境变量名
else if(IsDateTimeFormatString(输入))
... // 它是一个日期时间格式字符串
else if(input.IndexOfAny(Path.GetInvalidPathChars())<0)
... // 这是一个文件路径
其他的
抛出新异常();//不是有效的输入

我可以将日期时间格式字符串限制为仅“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;
}
如果您可以选择使用.NET3.5和LINQ,那么您可以使用直接处理字符,以及。这将使上述内容简化为:

bool valid = format.All(c => "yYmMdDsShH".Contains(c));
我会这样做:

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;
    }
}
公共静态类DateTimeFormatHelper
{
//使用字典而不是哈希集
//既然你说你在用.NET2.0
私有静态字典;
静态DateTimeFormatHelper()
{
_legalChars=新字典();
foreach(在“yymmdssh”中为char legalChar)
{
_legalChars.Add(legalChar,0);
}
}
公共静态bool IsPossibleDateTimeFormat(字符串格式)
{
if(string.IsNullOrEmpty(格式))
return false;//或任何对您有意义的内容
foreach(字符c格式)
{
如果(!_legalChars.ContainsKey(c))
返回false;
}
返回true;
}
}
当然,这可能是一个过于严格的定义,因为它排除了大多数人会认为有效格式,例如“YYYY MM DD”(因为它包括“-”字符)。 确定您希望允许哪些字符是您的判断权。

类似于

Regex regex = new Regex("^(y|Y|m|M|d|D|s|S|h|H)+$");
if (regex.IsMatch('DateTime String'))
{
    // 'valid' 
}
如果按字面意思搜索这些字符,而不是给定日期和时间的数字表示形式,如下所示:

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

public static bool IsValid(string str) {
    return Validator.IsMatch(str);
}
正则表达式的工作原理如下:

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
  • ^
    匹配字符串的开头
  • […]
    匹配括号中出现的任何字符
  • +
    匹配与上一项匹配的一个或多个字符
  • $
    匹配字符串的结尾

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

稍微缩短了Dan Tao的版本,因为字符串表示IEnumerable<&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");
      }
   }
[TestClass]
公共类UnitTest1{
private HashSet _legalChars=新HashSet(“yymmddssh”.ToCharArray());
公共bool IsPossibleDateTimeFormat(字符串格式){
if(string.IsNullOrEmpty(格式))
return false;//或任何对您有意义的内容
return!format.Except(_legalChars).Any();
}
[测试方法]
公共void TestMethod1(){
bool result=IsPossibleDateTimeFormat(“yydD”);
结果=IsPossibleDateTimeFormat(“abc”);
}
}

谢谢大家。我“支持”了你们所有人,并决定采用一种蛮力实现,它不使用字典/哈希集,也不将字符转换为字符串:

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;
}
private const string DateTimeFormatCharacters=“yymmddhhs”;
私有静态bool IsDateTimeFormatString(字符串输入)
{
foreach(输入中的字符c)
if(DateTimeFormatCharacters.IndexOf(c)<0)
返回false;
返回true;
}
有一个新项目,可以更快地完成这项工作:

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

@Reed:我刚刚意识到,当你发布那条评论时,我使用了
字典来代替它。我也想到了暴力方法。我希望我可能错过了系统中的一些东西。字符串或简单的正则表达式。哦,好吧,只要它能正常工作?@Tergiver:看来正则表达式选项是由SLaks提供的。但通常暴力在性能和可维护性方面都会胜出。至少在这样的情况下,逻辑不是特别复杂,暴力方法并不需要那么多代码,我个人更喜欢它。不过,这取决于您。@DanTao我非常怀疑这是否优于正确的正则表达式方法,我也不清楚为什么它更易于维护。您是在寻找字符串(yYmM..等)还是其中的数值?(100720(今天)?LINQ在.NET2中不存在。0@MikeD:这就是我的实现不使用它的原因;)它是一个纯.NET2实现。我刚才提到LINQ使这变得很容易…@MikeD:它使用的是字符串.Contains,它确实存在于.NET 2中(因此字符上的“ToString”):@Reed:我也想到了LINQ解决方案,但不幸的是,2.0要求不灵活。@Tergiver:这是.NET 2解决方案,而不是LINQ解决方案。这在.NET 2中可以完美地工作。(我要修改措辞,s