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



我有一个大列表(一个带有一个字段的表(,这些字符串是从管理不善的遗留数据库中导入的。我需要提取在每个字符串中恰好出现一次的个位数(用空格括起来((尽管字符串有时也有其他多位数(。 例如,从以下字符串:

"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语句中查找每个字符串是否有一个单独的数字,从而过滤我的列表。但它没有告诉我数字在哪里,所以我可以提取数字本身(使用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

但它给了我一个错误 无效地使用第Matching = .Execute(strToSearch)行的财产

使用正则表达式

如果要使用正则表达式,则需要定义一个 VBA 函数来实例化 RegExp 对象,将pattern属性设置为类似于sds(空格-数字-空格(,然后调用Execute方法来获取匹配项(或多个匹配项(,每个匹配项都将提供字符串中模式的索引。如果你想走这条路,这里有一些现有的Excel示例,但正则表达式操作在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库的引用。

即时窗口评估示例:

?InStr("abc 1 123", " 1 ")
4 
?RegexInStr("abc 1 123", "sws")
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 "* # *" 

怎么样:

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

最新更新