search数字不是较大expression式的特定数字(以英寸为单位)
我想使用一个Excel公式,当单元格中的文本包含术语“2”(两英寸)时,它将返回单元格中正确的索引,这可以通过search
function来实现。
问题是,我只想find实际上是“2”的实例,而不是其他实例,例如“1/2”或“12”等其他expression式。作品和它没有。
我认为使用正则expression式的VBA解决scheme将是最容易的,以便能够返回像1 1/2“的测量结果。
要input这个用户自定义函数(UDF), alt-F11
打开Visual Basic编辑器。 确保您的项目在“项目浏览器”窗口中突出显示。 然后,从顶部菜单中selectInsert/Module
然后将下面的代码粘贴到打开的窗口中。
要使用这个用户定义函数(UDF),input一个像
=FindMeasure(A1,$E$1)
在一些单元中,E1包含一个像2“或1 1/2”
Option Explicit Function FindMeasure(sSearch As String, ByVal sMeasure As String) Dim RE As Object, MC As Object, SM As Variant Dim sPat As String sPat = "\D(\s+)" & sMeasure & "|^" & sMeasure Set RE = CreateObject("vbscript.regexp") With RE .Global = False .MultiLine = True .Pattern = sPat End With If RE.test(sSearch) = True Then Set MC = RE.Execute(sSearch) SM = MC(0).submatches(0) FindMeasure = MC(0).firstindex + Len(SM) + IIf(Len(SM) > 0, 2, 1) Else FindMeasure = 0 End If End Function
编辑:审查我的答案显示,在某些情况下,不正确的结果将被返回。
- 如果在以数字结尾的测量之前有一个“字”,程序将无法识别测量结果。 这可以通过确保在测量之前至less有一个非数字string(通过修改正则expression式)来避免。 但是,如果整个单词由数字组成,测量将不被识别。
- 如果该行以
SPACE
开始,则测量不会被识别。 这可以通过修改代码和正则expression式来解决这个问题。 - 如果包含测量值的单元格或包含string的单元格为空,则结果将不正确。 这可以通过修改代码来testing这些条件来避免。
修改的代码
Option Explicit Function FindMeasure(sSearch As String, ByVal sMeasure As String) Dim RE As Object, MC As Object, SM As Variant Dim sPat As String sPat = "(\S*\D\S*\s+)" & sMeasure & "|(^\s*)" & sMeasure Set RE = CreateObject("vbscript.regexp") With RE .Global = False .MultiLine = True .Pattern = sPat End With If RE.test(sSearch) = True And _ Len(sSearch) > 0 And _ Len(sMeasure) > 0 Then Set MC = RE.Execute(sSearch) SM = MC(0).submatches(0) & MC(0).submatches(1) FindMeasure = MC(0).firstindex + Len(SM) + 1 Else FindMeasure = 0 End If End Function
用sMeasure = 2解释正则expression式
(\ S * \ d \ S * \ S +)2 “|(^ \ S *)2”
(\S*\D\S*\s+)2"|(^\s*)2"
选项:不区分大小写; 换行符$ ^
- 匹配这个替代
(\S*\D\S*\s+)2"
- 匹配下面的正则expression式并将其匹配到反向引用编号1
(\S*\D\S*\s+)
- 匹配不是“空白字符”的单个字符
\S*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
- 匹配不是“数字”的单个字符
\D
- 匹配不是“空白字符”的单个字符
\S*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
- 匹配一个“空白字符”
\s+
的单个字符- 在一次和无限次之间,尽可能多的次数,根据需要回馈(贪婪)
+
- 在一次和无限次之间,尽可能多的次数,根据需要回馈(贪婪)
- 匹配不是“空白字符”的单个字符
- 匹配string“2”“从字面上看
2"
- 匹配下面的正则expression式并将其匹配到反向引用编号1
- 或者匹配这个替代
(^\s*)2"
- 匹配下面的正则expression式并将其匹配到反向引用编号2
(^\s*)
- 断言位置在一行
^
的开头 - 匹配一个“空白字符”的单个字符
\s*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
*
- 在零和无限次之间,尽可能多次,根据需要回馈(贪婪)
- 断言位置在一行
- 匹配string“2”“从字面上看
2"
- 匹配下面的正则expression式并将其匹配到反向引用编号2
用RegexBuddy创build
使用:
=SEARCH(" 2"""," " & A1)-1
这个公式有三个小窍门:
- 我们search{空格} 2“
- 我们在string的开头放置一个空白
- 我们通过从头寸中减去一个来计算空白
编辑#1:
这可能会更好。 用A3中的数据和B2中的string尝试:
=IFERROR(IF(LEFT(A3,2)=$B$2,1,SEARCH(" " & $B$2, A3)+1),0)
如果我正在阅读这个权利的要求是:
1)如果它以2“开头(后跟一个空格)
2)string中间有2“(每边有空格)
3)string以2“结尾(前面有一个空格)应该是”OK“,否则为零
如果这些是要求这个公式应该工作:
=IF(OR(LEFT(A2,3)="2"" ",ISNUMBER(SEARCH(" 2"" ",A2)),RIGHT(A2,3)=" 2"""),"OK",0)
– 或者你可能不得不使用这个第二行取决于你的要求 –
=IF(OR(LEFT(A2,2)="2""",ISNUMBER(SEARCH(" 2"" ",A2)),RIGHT(A2,3)=" 2"""),"OK",0)