excel – stringvalidation

我有我需要validation的string,如

'AB01MCD10werdfGhjklOP01DEF03124' 

它以AB开头,后跟一个两个字符的数字,告诉我们有多less个“AB”字符(在这种情况下,它是01 ,只有1个字符是M)。 它应该跟随CD ,同样的行为,其次是OP ,这是可选的,即OP组可能或可能不存在。 最后它应该以EF gr结尾

  1. string以“AB”开头,是强制性的
  2. 随后“CD”再次强制
  3. 随后是可选的“OP”
  4. 紧随其后的是“EF”

我想validationA1中的string,并将validation结果放在B1中。

如果validation成功,则B1应该具有validation成功 ,否则错误:期望的“CD”,但发现“等等

请让我知道这样做的最好方法 – 是使用公式还是macros?

RegExpvalidationstring:

  1. AB开始,然后是一个2位数字,用于设置字母字符的数量
  2. 随后是CD ,然后是一个2位数字,用于设置要跟随的字母字符数
  3. 可选的OP如果存在,也有2位数字,用于设置字母字符的数量
  4. 接着是EF ,然后是一个2位数字,用于设置数字字符的数量

如果这是你想要的string,那么我将调整Len部分来标记testing中断的地方(即Error:Expected'CD')。 虽然我注意到在你的例子中,你最多可能有4个string的潜在问题,而不是单一的问题 )。

如果您对任何字符(来自Chris的代码将接受)感到满意,而不是您给出的字母和数字示例,那么可以简化RegExp

 Sub Test() Debug.Print Validator("AB01MCD10werdfGhjklOP01DEF03124") ' TRUE with optionalOP Debug.Print Validator("AB01MCD10werdfGhjklEF03124") ' TRUE without optional OP Debug.Print Validator("AB01MCD10weardfGhjklOP01DEF03124") ' fail as CD string is too long End Sub Function Validator(strIn As String) As Boolean Dim objRegex As Object Dim objRegexM As Object Set objRegex = CreateObject("vbscript.regexp") With objRegex .Pattern = "AB(\d{2})([az]+)CD(\d{2})([az]+)((?=OP)OP(\d{2})([az]+)){0,1}EF(\d{2})(\d+)" .ignoreCase = True If .Test(strIn) Then Set objRegexM = .Execute(strIn) With objRegexM(0) Validator = Len(.submatches(1)) = CLng(.submatches(0)) And Len(.submatches(3)) = CLng(.submatches(2)) And Len(.submatches(6)) = CLng(.submatches(5)) And Len(.submatches(8)) = CLng(.submatches(7)) End With End If End With End Function 

我写了这个函数可以为你做这个工作。 但是,如果你有超过AB / CD / EF,那么你将不得不相应地修改代码

 Private Sub Command1_Click() Dim A1 As String Dim B1 As String A1 = "AB01MCD10werdfGhjklOP01DEF03124" B1 = CodeValidate(A1) MsgBox B1 End Sub Function CodeValidate(ByVal TXT As String) As String Dim AB As Boolean Dim CD As Boolean Dim EF As Boolean Dim OP As Boolean Dim NextCounter As Integer Dim Buffer As String Dim result As String For i = 1 To Len(TXT) Buffer = Buffer & Mid(TXT, i, 1) If Len(Buffer) = 2 Then '============ Select Case Buffer Case "AB" If AB = False And CD = False And EF = False Then AB = True NextCounter = Val(Mid(TXT, i + 1, 2)) i = i + 2 + NextCounter Buffer = "" Else result = "Error: Duplicate [AB] found at position " & i & "." Exit For End If Case "CD" If AB = True And CD = False And EF = False Then CD = True NextCounter = Val(Mid(TXT, i + 1, 2)) i = i + 2 + NextCounter Buffer = "" Else result = "Error: Duplicate [CD] found at position " & i & "." Exit For End If Case "EF" If AB = True And CD = True And EF = False Then EF = True NextCounter = Val(Mid(TXT, i + 1, 2)) i = i + 2 + NextCounter Buffer = "" Else result = "Error: Duplicate [EF] found at position " & i & "." Exit For End If Case "OP" If OP = False Then OP = True NextCounter = Val(Mid(TXT, i + 1, 2)) i = i + 2 + NextCounter Buffer = "" Else result = "Error: Duplicate [OP] found at position " & i & "." Exit For End If Case Else If AB = False Then result = "Error: Expecting [AB] but found [" & Buffer & "] at position " & i & "." Exit For ElseIf AB = True And CD = False Then result = "Error: Expecting [CD] but found [" & Buffer & "] at position " & i & "." Exit For ElseIf AB = True And CD = True And EF = False Then result = "Error: Expecting [EF] but found [" & Buffer & "] at position " & i & "." Exit For End If End Select '============ End If Next If result = "" Then result = "Validation Success" End If CodeValidate = result End Function 

基于也是EFnn<n characters>forms的EF术语,试试这个

 Function CheckString(r As Range) As String Dim str As String Dim substr As String Dim v As Long str = r.Value If Left$(str, 2) = "AB" Then str = Mid$(str, 3) substr = Left$(str, 2) str = Mid$(str, 3) If IsNumeric(substr) Then v = Val(substr) str = Mid$(str, v + 1) ' CD If Left$(str, 2) = "CD" Then str = Mid$(str, 3) substr = Left$(str, 2) str = Mid$(str, 3) If IsNumeric(substr) Then v = Val(substr) str = Mid$(str, v + 1) ' OP or EF If Left$(str, 2) = "OP" Then str = Mid$(str, 3) substr = Left$(str, 2) str = Mid$(str, 3) If IsNumeric(substr) Then v = Val(substr) str = Mid$(str, v + 1) ' EF If Left$(str, 2) = "EF" Then str = Mid$(str, 3) substr = Left$(str, 2) str = Mid$(str, 3) If IsNumeric(substr) Then v = Val(substr) If Len(str) = v Then CheckString = "Validation Success" Else ' No more after EF CheckString = "Error: Expecting " & v & " characters after EF" End If Else ' number follows EF CheckString = "Error: Expected number following EF" End If Else CheckString = "Error: Expecting EF" End If Else ' number follows CD CheckString = "Error: Expected number following CD" End If ' EF ElseIf Left$(str, 2) = "EF" Then str = Mid$(str, 3) substr = Left$(str, 2) str = Mid$(str, 3) If IsNumeric(substr) Then v = Val(substr) If Len(str) = v Then CheckString = "Validation Success" Else ' No more after EF CheckString = "Error: Expecting " & v & " characters after EF" End If Else ' number follows EF CheckString = "Error: Expected number following EF" End If Else CheckString = "Error: Expecting EF" End If Else ' number follows CD CheckString = "Error: Expected number following CD" End If Else ' Begin with "CD" CheckString = "Error: Expected CD" End If Else ' number follows AB CheckString = "Error: Expected number following AB" End If Else ' Begin with "AB" CheckString = "Error: Expected AB" End If End Function 

这里有第一个破解,有可能是更好的方法,正则expression式不是我的东西,但它适用于这个例子:

 Public Function ValString(strInput As String) As String Static regEx As Object Dim x As Long Dim temp$ Dim matches As Object If regEx Is Nothing Then Set regEx = CreateObject("vbscript.regexp") With regEx .Pattern = "^AB([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "AB") + 2, 2)) & "})CD([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "CD") + 2, 2)) & "})(OP([0-9]{2})[A-Za-z]+EF[0-9]+|EF[0-9]+)$" Set matches = .Execute(strInput) If .Test(strInput) Then ValString = "Validation Success" Exit Function Else .Pattern = "(AB|CD|EF)" .Global = True Set matches = .Execute(strInput) If matches.Count > 0 Then temp$ = "ABCDEF" For x = 0 To matches.Count - 1 temp$ = Replace(temp$, matches(x), vbNullString) ValString = ValString & ",'" & matches(x) & "'" Next x If Len(temp$) > 1 Then ValString = "Error:Expected '" & temp$ & "', Found " & Right(ValString, Len(ValString) - 1) Else ValString = "Error:Paramaters Found, invalid string" End If Else ValString = "Error:Expected 'CD', Found nothing" End If End If End With End Function 

根据克里斯的build议,编辑后强制执行A​​B和CD后面的2位数字,规定以下字符的长度

如果字符OP遵循相同的模式,那么你可以使用:

 .Pattern = "^AB([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "AB") + 2, 2)) & "})CD([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "CD") + 2, 2)) & "})(OP([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "OP") + 2, 2)) & "})EF[0-9]+|EF[0-9]+)$" 

如上所述,但EF也遵循相同的模式,但只是数字:

 .Pattern = "^AB([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "AB") + 2, 2)) & "})CD([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "CD") + 2, 2)) & "})(OP([0-9]{2})([A-Za-z]{" & Val(Mid(strInput, InStr(1, strInput, "OP") + 2, 2)) & "})(EF[0-9]{2})([0-9]{" & Val(Mid(strInput, InStr(1, strInput, "EF") + 2, 2)) & "})|(EF[0-9]{2})([0-9]{" & Val(Mid(strInput, InStr(1, strInput, "EF") + 2, 2)) & "}))$"