VBA: REGEX LOOKBEHIND MS ACCESS 2010

У меня есть функция, которая была написана так, чтобы VBA можно было использовать в MS Access. Я хочу сделать следующее.

Я установил свой код ниже. Все до продукта работает отлично, но попытка получить информацию просто возвращает «», что странно, так как когда я запускаю его в Notepad ++, он работает отлично

Итак, он ищет буквы MIP и один из трехбуквенных кодов (любой из них)

 StringToCheck = "MADHUBESOMIPTDTLTRCOYORGLEJ"

' PART 1
' If MIP appears in the string, then delete any of the following codes if they exist - DOM, DOX, DDI, ECX, LOW, WPX, SDX, DD6, DES, BDX, CMX,
' WMX, TDX, TDT, BSA, EPA, EPP, ACP, ACA, ACE, ACS, GMB, MAL, USP, NWP.
' EXAMPLE 1.  Flagged as: MADHUBESOMIPTDTLTRCOYORGLEJ, should be MADHUBESOMIPLTRCOYORGLEJ


Do While regexp(StringToCheck, "MIP(DOM|DOX|DDI|ECX|LOW|WPX|SDX|DD6|DES|BDX|CMX|WMX|TDX|TDT|BSA|EPA|EPP|ACP|ACA|ACE|ACS|GMB|MAL|USP|NWP|BBX)", False) <> ""
    ' SELECT EVERYTHING BEFORE THE THREE LETTER CODES
     strPart1 = regexp(StringToCheck, ".*^[^_]+(?=DOM|DOX|DDI|ECX|LOW|WPX|SDX|DD6|DES|BDX|CMX|WMX|TDX|TDT|BSA|EPA|EPP|ACP|ACA|ACE|ACS|GMB|MAL|USP|NWP|BBX)", False)
    ' SELECT EVERYTHING AFTER THE THREE LETTER CODES
     strPart2 = regexp(StringToCheck, "(?<=(DOM|DOX|DDI|ECX|LOW|WPX|SDX|DD6|DES|BDX|CMX|WMX|TDX|TDT|BSA|EPA|EPP|ACP|ACA|ACE|ACS|GMB|MAL|USP|NWP|BBX).*", False)
StringToCheck = strPart1 & strPart2
Loop

Функция, которую я использую, которую я взял из Интернета, приведена ниже.

Function regexp(StringToCheck As Variant, PatternToUse As String, Optional CaseSensitive As Boolean = True) As String

On Error GoTo RefErr:

Dim re As New regexp
re.Pattern = PatternToUse
re.Global = False
re.IgnoreCase = Not CaseSensitive

Dim m
For Each m In re.Execute(StringToCheck)
    regexp = UCase(m.Value)
Next

RefErr:
    On Error Resume Next

End Function

person John Smith    schedule 14.08.2014    source источник
comment
Движок MS Scripting RE не поддерживает просмотр назад.   -  person Alex K.    schedule 14.08.2014
comment
Если ЧАСТЬ 1 — это все, что вам нужно сделать, вам лучше использовать instr для поиска MIP, а затем 3-шаговый цикл для удаления токенов (IMO, это было бы лучше, даже если бы lbh был доступен)   -  person Alex K.    schedule 14.08.2014


Ответы (2)


Просто сделайте это в два шага:

  1. Проверить, есть ли в строке MIP
  2. Если это так, удалите другие коды.

Как это:

Sub Test()
  Dim StringToCheck As String
  StringToCheck = "MADHUBESOMIPTDTLTRCOYORGLEJ"

  Debug.Print StringToCheck
  Debug.Print CleanupString(StringToCheck)
End Sub

Function CleanupString(str As String) As String
  Dim reCheck As New RegExp
  Dim reCodes As New RegExp

  reCheck.Pattern = "^(?:...)*?MIP"
  reCodes.Pattern = "^((?:...)*?)(?:DOM|DOX|DDI|ECX|LOW|WPX|SDX|DD6|DES|BDX|CMX|WMX|TDX|TDT|BSA|EPA|EPP|ACP|ACA|ACE|ACS|GMB|MAL|USP|NWP|BBX)"
  reCodes.Global = True

  If reCheck.Test(str) Then
    While reCodes.Test(str)
      str = reCodes.Replace(str, "$1")
    Wend
  End If

  CleanupString = str
End Function

Обратите внимание, что цель (?:...)*? состоит в том, чтобы сгруппировать буквы по три.


Поскольку механизм регулярных выражений VBScript поддерживает просмотр вперед, вы, конечно, можете сделать это и в одном регулярном выражении:

Function CleanupString(str As String) As String
  Dim reClean As New RegExp

  reClean.Pattern = "^(?=(?:...)*?MIP)((?:...)*?)(?:DOM|DOX|DDI|ECX|LOW|WPX|SDX|DD6|DES|BDX|CMX|WMX|TDX|TDT|BSA|EPA|EPP|ACP|ACA|ACE|ACS|GMB|MAL|USP|NWP|BBX)"

  While reClean.Test(str)
    str = reClean.Replace(str, "$1")
  Wend

  CleanupString = str
End Function

Лично мне больше нравится двухшаговый шаблон проверки/удаления, потому что он намного более очевиден и, следовательно, более удобен в сопровождении.

person Tomalak    schedule 14.08.2014
comment
Спасибо Томалак, это было именно то, что я искал. Я мог бы использовать другой метод, отличный от Reg-ex, но это только первая часть процесса из 6 частей, поэтому я отмечаю его как ответ. - person John Smith; 18.08.2014

Вариант без RE:

Function DeMIPString(StringToCheck As String) As String
    If Not InStr(StringToCheck, "MIP") Then
        DeMIPString = StringToCheck
    Else
        Dim i As Long
        For i = 1 To Len(StringToCheck) Step 3
            Select Case Mid$(StringToCheck, i, 3)
                Case "MIP", "DOM", "DOX", "DDI", "ECX", "LOW", "WPX", "SDX", "DD6", "DES", "BDX", "CMX", "WMX", "TDX", "TDT", "BSA", "EPA", "EPP", "ACP", "ACA", "ACE", "ACS", "GMB", "MAL", "USP", "NWP":
                Case Else
                    DeMIPString = DeMIPString & Mid$(StringToCheck, i, 3)
            End Select
        Next
    End If
End Function
person Alex K.    schedule 14.08.2014