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