正则表达式预测匹配第一组或第二组数字

时间:2015-05-28 13:33:24

标签: regex vba

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:   

5 个答案:

答案 0 :(得分:2)

直到第二次出现4位数组,或直到第一组为止,如果只有一个使用此模式

^((?:.*?\d{4})?.*?)(?=\s*\b\d{4}\b)

Demo

以下评论,请使用此模式

^((?:.*?\d{4})?.*?(?=\s*\b\d{4}\b)|.*)

Demo

答案 1 :(得分:1)

  

匹配除空格之外的所有内容,直到最后一个4位数字

您可以使用以下内容:

(?:(?! ).)+(?=.*\b\d{4}\b)

请参阅DEMO

答案 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