我遇到了VB.NET IsDate函数的问题 - 它对不是有效日期的字符串值返回true,例如" 367 7"和" 10,600"所以我决定编写自己的功能,并希望听到一些关于可能的改进的反馈。真的很感激有价值的投入。
Function IsValidDate(ByVal str As String) As Boolean
str = str.Replace(" ", "").Trim()
'If (str Is Nothing) Then
' Return False
'End If
'If IsNumeric(str) Then
' Return False
'End If
'If Regex.IsMatch(str, "^[A-Za-z ]+$") Then
' Return False
'End If
If Regex.IsMatch(str, "^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$") Then
''mm/dd/yyyy or mm-dd-yyyy
Return True
ElseIf Regex.IsMatch(str, "^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.]\d\d$") Then
''mm/dd/yy or mm-dd-yy
Return True
ElseIf Regex.IsMatch(str, "^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$") Then
''dd-mm-yyyy or dd/mm/yyyy
Return True
ElseIf Regex.IsMatch(str, "^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$") Then
''yyyy-mm-dd or yyyy/mm/dd
Return True
End If
Return False
End Function
我在数字字符串中处理了一个可能的空格(例如:" 367 7"然后我确保它返回false,如果值是数字或什么都没有。我也删除了所有字符串字母数字。请让我知道您的想法。谢谢
P.S>编辑:我在开头注释了几行,因为我觉得它们可以被删除,因为如果字符串与其中一个正则表达式不匹配,它将返回false
答案 0 :(得分:2)
试过这样的事吗?
sub do_something {
$args = $_[0];
$third_key = $$args{key3} ? $$args{key3} : '';
print $$args{key1} . $$args{key2} . $$args{key3};
}
从这里你可以改变引号中的格式。
<强>!EDIT!强>
由于我的声誉,我无法添加评论,但如果您的评论中使用了您的格式数组并使用我的代码,而不是我在那里的格式,请将您的数组格式放在其位置。它对我来说很好。
Function IsValidDate(ByVal str As String) As Boolean
Dim test As Date
If Date.TryParseExact(str, "yyyy/MM/dd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture, Globalization.DateTimeStyles.None, test) Then
Return True
Else
Return False
End If
End Function
这不会重新组织你的输入,而只是一个布尔返回,看看它是否与你指定的格式匹配,这是你原来想要的正确吗?
答案 1 :(得分:1)
您是否考虑过DateTime.ParseExact而不是使用正则表达式?它允许您定义支持的确切格式。
答案 2 :(得分:1)
在我自己的代码中遇到这种情况,我发现了&#39; TryParseExact&#39;功能明显慢于使用一系列的Regex.Match&#39;调用
这是我编写的用于检查我正在寻找的格式的函数,它比TryParseExact快了大约10倍。
这比TryParseExact的缺点是它不会检查所有边缘情况,例如&#39; 31不是11月的有效日期&#39;或者&#39; 29在某些年份不是2月份的有效日期&#39;。所以只要你愿意放弃这些捕获量,那就更快了。
Public Shared Function ChkDate(ByVal Value As Object) As Boolean
If Value.GetType().Name = "DateTime" Then
Return True
ElseIf Not String.IsNullOrWhiteSpace(Value.ToString()) Then
Dim TempStr As String = Value.ToString()
' Please speed test before making any changes to this function, the below version is much faster than Date.TryParse or Date.TryParseExact
If InStr(TempStr, ".") <> 0 AndAlso TempStr.Split({"."c}).Length = 3 Then ' d.M.yyyy
Dim TempArray() As String = TempStr.Split({"."c})
Dim NewString As String = TempArray(1) & "/" & TempArray(0) & "/" & TempArray(2)
ElseIf InStr(TempStr, "/") <> 0 AndAlso RegularExpressions.Regex.IsMatch(TempStr, "\A[01]{0,1}[0-9]{1}/[0123]{0,1}[0-9]{1}/[0-9]{4}\z") Then ' M/d/yyyy
Return True
ElseIf InStr(TempStr, "-") <> 0 AndAlso RegularExpressions.Regex.IsMatch(TempStr, "\A[0-9]{4}-[01]{0,1}[0-9]{1}-[0123]{0,1}[0-9]{1}\z") Then ' yyyy-M-d
Return True
ElseIf InStr(TempStr, "-") <> 0 AndAlso InStr(TempStr, ":") <> 0 AndAlso RegularExpressions.Regex.IsMatch(TempStr, "\A[0-9]{4}-[01]{0,1}[0-9]{1}-[0123]{0,1}[0-9]{1} [01]{0,1}[0-9]{1}:[01]{0,1}[0-6]{1}:[01]{0,1}[0-6]{1}\z") Then ' yyyy-M-d H:mm:ss
Return True
ElseIf InStr(TempStr, "/") <> 0 AndAlso InStr(TempStr, ":") <> 0 AndAlso RegularExpressions.Regex.IsMatch(TempStr, "\A[01]{0,1}[0-9]{1}/[0123]{0,1}[0-9]{1}/[0-9]{4} [01]{0,1}[0-9]{1}:[01]{0,1}[0-6]{1}\z") Then ' M/d/yyyy h:mm
Return True
ElseIf RegularExpressions.Regex.IsMatch(TempStr, "\A[0-9]{4}[01]{1}[0-9]{1}[0123]{1}[0-9]{1}\z") Then ' yyyyMMdd
Return True
ElseIf RegularExpressions.Regex.IsMatch(TempStr, "\A[0-9]{4}[01]{0,1}[0-9]{1}[0123]{0,1}[0-9]{1}[01]{0,1}[0-9]{1}[01]{0,1}[0-6]{1}\z") Then ' yyyyMMddHHmm
Return True
Else
Return IsDate(TempStr)
End If
End If
Return False
End Function