我可以使用正则表达式、Like 运算符、and/or Instr() 在较大的字符串中查找模式的索引吗?

Can I use regular expressions, the Like operator, and/or Instr() find the index of a pattern within a larger string?

我有一长串非标准化字符串(table,只有一个字段),这些字符串是从管理不善的遗留数据库中导入的。我需要提取在每个字符串中恰好出现一次的个位数(用空格包围)(尽管字符串有时也有其他多位数字)。例如,来自以下字符串:

"Quality Assurance File System And Records Retention Johnson, R.M. 004 4 2999 ss/ds/free ReviewMo = Aug Effective 1/31/2012 FileOpen-?"

我想提取数字 4(或 4 在字符串中的位置,即 71)

我可以用

WHERE rsLegacyList.F1 LIKE "* # *" 

select 语句中查找 if 每个字符串都有一个单独的数字,从而过滤我的列表。但它没有告诉我 数字在哪里,所以我可以提取数字本身(使用 mid() 函数)并开始对列表进行排序。目标是创建一个单独包含该数字的第二个字段,作为对第一个字段中较大字符串进行排序的方法。

有没有办法结合使用 Instr() 和正则表达式来查找正则表达式在较大字符串中出现的位置?像

intMarkerLocation = instr(rsLegacyList.F1, Like "* # *")

但这真的有效吗?

我感谢任何可以完全避免该问题的建议或解决方法。


@Lee Mac,我做了一个函数RegExFindStringIndex,如下所示:

Public Function RegExFindStringIndex(strToSearch As String, strPatternToMatch As String) As Integer

    Dim regex                       As RegExp
    Dim Matching                    As Match

    Set regex = New RegExp

    With regex
        .MultiLine = False
        .Global = True
        .IgnoreCase = False
        .Pattern = strPatternToMatch
        Matching = .Execute(strToSearch)
        RegExFindStringIndex = Matching.FirstIndex
    End With

    Set regex = Nothing
    Set Matching = Nothing
End Function

但是它给我一个错误 Invalid use of 属性 at line Matching = .Execute(strToSearch)

怎么样:

select
    instr(rsLegacyList.F1, " # ") + 1 as position
from rsLegacyList.F1
where rsLegacyList.F1 LIKE "* # *"

使用正则表达式

如果要使用正则表达式,则需要定义一个 VBA 函数来实例化 RegExp 对象,将 pattern 属性 设置为 \s\d\s (whitespace-digit-whitespace) 然后调用 Execute 方法来获得一个匹配项(或多个匹配项),每个匹配项将提供字符串中模式的索引。如果您想走这条路,here 是 Excel 的一些现有示例,但 RegExp 操作在 MS Access 中是相同的。

下面是一个示例函数,演示如何使用 Execute 方法返回的第一个结果:

Public Function RegexInStr(strStr As String, strPat As String) As Integer
    With New RegExp
        .Multiline = False
        .Global = True
        .IgnoreCase = False
        .Pattern = strPat
        With .Execute(strStr)
            If .Count > 0 Then RegexInStr = .Item(0).FirstIndex + 1
        End With
    End With
End Function

请注意,上面使用了早期绑定,因此您需要将对 Microsoft VBScript 正则表达式 5.5 库的引用添加到您的项目中。

示例立即 Window 评估:

?InStr("abc 1 123", " 1 ")
 4 
?RegexInStr("abc 1 123", "\s\w\s")
 4 

使用 InStr

在查询中使用内置 instr 函数的替代方法可能是以下不优雅(并且可能非常慢)的查询:

select
    switch
    (
        instr(rsLegacyList.F1," 0 ")>0,instr(rsLegacyList.F1," 0 ")+1,
        instr(rsLegacyList.F1," 1 ")>0,instr(rsLegacyList.F1," 1 ")+1,
        instr(rsLegacyList.F1," 2 ")>0,instr(rsLegacyList.F1," 2 ")+1,
        instr(rsLegacyList.F1," 3 ")>0,instr(rsLegacyList.F1," 3 ")+1,
        instr(rsLegacyList.F1," 4 ")>0,instr(rsLegacyList.F1," 4 ")+1,
        instr(rsLegacyList.F1," 5 ")>0,instr(rsLegacyList.F1," 5 ")+1,
        instr(rsLegacyList.F1," 6 ")>0,instr(rsLegacyList.F1," 6 ")+1,
        instr(rsLegacyList.F1," 7 ")>0,instr(rsLegacyList.F1," 7 ")+1,
        instr(rsLegacyList.F1," 8 ")>0,instr(rsLegacyList.F1," 8 ")+1,
        instr(rsLegacyList.F1," 9 ")>0,instr(rsLegacyList.F1," 9 ")+1,
        true, null
    ) as intMarkerLocation
from
    rsLegacyList
where 
    rsLegacyList.F1 like "* # *"