[英]excel-vba regex pattern
我希望以下函数验证字符串,如果它看起来像这样:
每个之间可能是一个空格,2个可选部分的顺序无关紧要(“2 box male”==“2 male box”)
但是除了做任何有用的事情之外,这个函数除了以数字开头的所有东西:
Function validAmount(Zelle As Variant)
Set regEx = CreateObject("VBScript.RegExp")
regEx.IgnoreCase = True
regEx.Pattern = "\d\s?(pcs|pieces|piece|pc|stk|bags|bag|box|bx|boxes)?\s?(male|m|female|f)?"
If (regEx.test(Zelle)) Then
validAmount = True
Else
validAmount = False
End If End Function
我希望我的错误不是太愚蠢
编辑:我想到了一个额外的功能。 我怎么能允许上面的图案的多个实体分开“,”像“1盒女性,3袋米,4个男性”
ps:这两种解决方案都运行良好,但允许这样的“1男性女性”或“2个盒子包”
edit2:首先:我非常感谢你的帮助! 我自己永远不会解决这个问题! 一旦一切按预期工作,我想点击“已解决”(无法点击“向上”,因为我的声誉仍然太低)。 如果我早点点击它,我很抱歉。 这是我的第一个问题,我对你的答案来得多快有点不知所措:)
我想我无法表达我的意愿:D真的很抱歉! 这是第三次尝试:只允许(至少)允许每个组中的一个。 真正的输入应该是:“#box gender”“#gender box”“#box”“#gender”“#”但不是:“#box box”或“#sex gender”
@sln:我认为你的第一次看起来更像我想要它但它允许同一组的两个实例,即使它找不到它:((对于JMax解决方案也一样)
@JMax:我喜欢你的“分裂”解决方案! 甚至没有想到这个简单的伎俩:DI在正则表达式上如此固定,以至于没有想到其他任何东西
这是一个尝试:
Function validAmount(Zelle As String)
Dim sBoxes As String, sGender As String
Dim arr() As String
Dim i As Integer
arr = Split(Zelle, ",")
sBoxes = "pcs|pieces|piece|pc|stk|bags|bag|box|bx|boxes"
sGender = "male|m|female|f"
validAmount = True
For i = 0 To UBound(arr)
Set regEx = CreateObject("VBScript.RegExp")
regEx.IgnoreCase = True
regEx.Pattern = "\d\s?(((" & sBoxes & ")?\s?(" & sGender & "))|((" & sGender & ")?\s?(" & sBoxes & ")))?$"
If (regEx.test(arr(i))) Then
validAmount = validAmount And True
Else
validAmount = validAmount And False
End If
Next i
End Function
这是一个测试程序:
Sub unitTest()
'could use debug.Assert too
Debug.Print (validAmount("1 box") & " should be True")
Debug.Print (validAmount("1 boxe male") & " should be False")
Debug.Print (validAmount("1 pcs female") & " should be True")
Debug.Print (validAmount("1boxes") & " should be True")
Debug.Print (validAmount("1 female pcs") & " should be True")
Debug.Print (validAmount("boxes") & " should be False")
Debug.Print (validAmount("2 male box") & " should be True")
Debug.Print (validAmount("1 mytest") & " should be False")
Debug.Print (validAmount("1 pc box") & " should be False")
Debug.Print (validAmount("1 box box") & " should be False")
Debug.Print (validAmount("1 box female, 3 bags m, 4pcs male") & " should be True")
End Sub
我已经将框和性别更改为字符串,以便您可以在模式中添加两者(我不知道如何在没有这个技巧的情况下检查顺序 。有没有人有更好的主意?
我还添加了一个$
告诉Excel这是字符串的结尾,否则任何以数字开头的字符串都会通过。
如果您的vba至少可以做前瞻性断言,这将有效。 我以为我读它像javascript一样的正则表达式。 如果是这样,这是有效的。 但如果没有,请忽视。
它不是那么容易解释,所以它的功能有细分。
^\\d(?:\\s?(?:(?!\\1)(?:pcs|pc|pieces|piece|stk|bags|bag|boxes|box|bx)()|(?!\\2)(?:male|m|female|f)()|)){2}$
扩展:
^ # Begining of string
\d # A digit
(?: # Grouping
\s? # Optional whitespace
(?: # Grouping
(?!\1) # Never been here before, capt grp 1 is undefined
(?:pcs|pc|pieces|piece|stk|bags|bag|boxes|box|bx) # One of these alternations is found
() # Mark we've been here, Capt Grp 1 is defined
| # OR ..
(?!\2) # Never been here before, capt grp 2 is undefined
(?:male|m|female|f) # One of these alternations is found
() # Mark we've been here, Capt Grp 2 is defined
| # OR ..
# Nothing, this allows to pick optional \s only, or combined
) # End grouping
){2} # End grouping, do exactly 2 times
$ # End of string
编辑
要一次性处理您的编辑,以下正则表达式将起作用。 如果您想使任一组替换都可以接受,请将它们组合成一个替换。 如果发生命名冲突,可能会出现这种问题。 这是因为你做了两次。 此外,间距是一个大问题吗?
下面有2个正则表达式。
这个对间距非常严格。 它更符合你陈述问题的方式。 这不是一个好主意。
^(?=\\d)(?:\\d(?:\\s?(?:pcs|pc|pieces|piece|stk|bags|bag|boxes|box|bx|male|m|female|f|)){2}(?:,\\s?(?=\\d)|$))+$
这个完全放松了间距,同时保留了核心非空白形式。
这是推荐的版本。 随意更改正则表达式中的间距结构。
^(?=\\s*\\d)(?:\\s*\\d(?:\\s*(?:pcs|pc|pieces|piece|stk|bags|bag|boxes|box|bx|male|m|female|f|)){2}\\s*(?:,(?=\\s*\\d)|$))+$
在这里进行了扩展,请参阅上面原始扩展正则表达式中的注释。
^
(?=\s*\d)
(?:
\s*
\d
(?:
\s*
(?:pcs|pc|pieces|piece|stk|bags|bag|boxes|box|bx|male|m|female|f|)
){2}
\s*
(?:
, (?=\s*\d)
| $
)
)+
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.