VBA中的正则表达式。
我使用以下正则表达式匹配4位数组的第二次出现,或者如果只有一个组,则使用第一组:
\b\d{4}\b(?!.+\b\d{4}\b)
现在我需要做相反的事情:我需要匹配所有内容,直到第二次出现4位数组,或者直到第一组只有一个。如果没有4位数组,则捕获整个字符串。
这就足够了。
但也有一个更好的奖励" route:如果存在匹配所有内容的方法,直到一个4位数的组可选地后跟一些随机文本,但只有在其后没有其他4位数组的情况下。如果存在第二组4位数,则捕获所有内容直到该组(包括第一组和句点,但不包括逗号)。如果没有组,请捕获所有内容。如果该行以4位数组开头,则不进行任何捕获。
我明白这也可以(应该?)以前瞻的方式完成,但我没有任何运气来弄清楚它们是如何为此目的而工作的。
示例:
Input: String.String String 4444
Capture: String.String String 4444
Input: String4444 8888 String
Capture: String4444
Input: String String 444 . B, 8888
Capture: String String 444 . B
奖金案例:
Input: 8888 String
Capture:
答案 0 :(得分:2)
直到第二次出现4位数组,或直到第一组为止,如果只有一个使用此模式
^((?:.*?\d{4})?.*?)(?=\s*\b\d{4}\b)
以下评论,请使用此模式
^((?:.*?\d{4})?.*?(?=\s*\b\d{4}\b)|.*)
答案 1 :(得分:1)
答案 2 :(得分:1)
对于您的基本情况(由您标记为足够),这将起作用:
((?:(?!\d{4}).)*(?:\d{4})?(?:(?!\d{4}).)*)(?=\d{4})
如果需要,您可以在\d{4}
内部填充每个\b
。
查看演示here。
答案 3 :(得分:1)
您可以在VBA中使用此正则表达式来捕获具有4位数字的行,或者那些没有4位数字的行:
^((?:.*?[0-9]{4})?.*?(?=\s*?[0-9]{4})|(?!.*[0-9]{4}).*)
请参阅demo,它在VBA中的工作方式应该相同。
正则表达式由2个备选方案组成:(?:.*?[0-9]{4})?.*?(?=\s*?[0-9]{4})
和(?!.*[0-9]{4}).*
。
(?:.*?[0-9]{4})?.*?(?=\s*?[0-9]{4})
匹配0或更多(尽可能少)字符,前面有0或1个字符序列,后跟4位数字,后跟可选空格和4位数字
(?!.*[0-9]{4}).*
匹配任何数量的内部没有4位数字的字符。
请注意,要仅匹配整数(不是其他字的一部分),您需要围绕\b
模式添加[0-9]{4}
(即\b[0-9]{4}\b
)。
答案 4 :(得分:0)
如果有人有兴趣,我会欺骗以完全解决我的问题。
在this answer上构建,它解决了我的绝大多数数据集,我使用程序逻辑来捕获一些很少见的用例。单个正则表达式似乎很难涵盖所有情况,所以这似乎是一个可行的替代方案。
问题说明here。
代码还没有防弹,但这是要点:
Function cRegEx (str As String) As String
Dim rExp As Object, rMatch As Object, regP As String, strL() As String
regP = "^((?:.*?[0-9]{4})?.*?(?:(?=\s*[0-9]{4})|(?:(?!\d{4}).)*)|(?!.*[0-9]{4}).*)"
' Encountered two use-cases that weren't easily solvable with regex, due to the already complex pattern(s).
' Split str if we encounter a comma and only keep the first part - this way we don't have to solve this case in the regex.
If InStr(str, ",") <> 0 Then
strL = Split(str, ",")
str = strL(0)
End If
' If str starts with a 4-digit group, return an empty string.
If cRegExNum(str) = False Then
Set rExp = CreateObject("vbscript.regexp")
With rExp
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = regP
End With
Set rMatch = rExp.Execute(str)
If rMatch.Count > 0 Then
cRegEx = rMatch(0)
Else
cRegEx = ""
End If
Else
cRegEx = ""
End If
End Function
Function cRegExNum (str As String) As Boolean
' Does the string start with 4 non-whitespaced integers?
' Return true if it does
Dim rExp As Object, rMatch As Object, regP As String
regP = "^\d{4}"
Set rExp = CreateObject("vbscript.regexp")
With rExp
.Global = False
.MultiLine = False
.IgnoreCase = True
.Pattern = regP
End With
Set rMatch = rExp.Execute(str)
If rMatch.Count > 0 Then
cRegExNum = True
Else
cRegExNum = False
End If
End Function