簡體   English   中英

正則表達式先行查找以匹配第一組或第二組數字之前的所有內容

[英]Regex lookahead to match everything prior to 1st OR 2nd group of digits

VBA中的正則表達式。

我正在使用以下正則表達式來匹配4位數字組的第二次出現,如果只有一個組,則匹配第一組:

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

現在,我需要做相反的事情:我需要匹配所有內容,直到出現第二個4位數組,或者如果只有一個,則匹配到第一組。 如果沒有4位數字組,則捕獲整個字符串。

這樣就足夠了。

但是,還有一條更可取的“加分”路線:如果存在一種方法來匹配所有內容,直到一個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:   

直到第二個出現一個四位數的組為止,或者直到只有一個使用第一個組為止,直到第一個出現為止

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

演示版


根據下面的評論,使用此模式

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

演示版

匹配除空格外的所有內容,直到最后出現一個4位數字的單詞

您可以使用以下內容:

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

演示

對於您的基本情況(由您標記為足夠),這將起作用:

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

如果需要,可以在內部用\\b填充每個\\d{4}

在此處查看演示。

您可以在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位數字的任意數量的字符。

請注意,僅匹配整數(不包括其他部分),您需要在[0-9]{4}模式(即\\b[0-9]{4}\\b )周圍添加\\b

如果有人感興趣,我會作弊以完全解決我的問題。

基於此答案 (它解決了我的絕大多數數據集),我使用程序邏輯來捕獲一些罕見的用例。 似乎很難獲得一個正則表達式來涵蓋所有情況,因此這似乎是一個可行的選擇。

問題在這里說明。

該代碼還不是防彈的,但這是要點:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM