嗨,我是正则表达式的新手。我需要一个在VBA中使用的表达式,该表达式将提取长度不超过1位数的第一个数字字符串,而不用括号括在字符串中。例如字符串:
"SHIRT L/S (07565) 07996 REF OR VLINE L"
我要从字符串中获取07996。
答案 0 :(得分:4)
您可以尝试/([0-9]{2,})(?![^\(]*\))/g
。
第二部分用括号括起来时将与您的初始模式不匹配。
答案 1 :(得分:1)
我知道,这很痛苦,但是我不能推荐您足够多的人进行常规的研究。我是C#,JS类的人,因此未经VBA测试,但这应该是一个很好的起点:
您想要什么:
\d+(?!\()
不要错过“编辑”部分
说明:
\d+
这只是匹配数字。您可以在[]中匹配一个字符范围(参考asci表),可以使用[1-9],但是有一个数字“ \ d”的快捷方式。您希望字符串中的所有数字至少出现一次。您可以使用{minimum,maximum}(可能为{1,})来执行此操作,但是该“ +”还有一个快捷方式-至少一次。
(?<!\()
负向隐藏-表示您想要不带此前缀(不包括此前缀)的匹配项-这就是环视功能。这个正在寻找(,您必须转义“ \(”
(?<= )
正向后看-做完全相反的事情,查找带有特定前缀(不包含在匹配项中)的匹配项。这是一个空的地方。
(?= )
正向超前-唯一的区别是,它朝相反的方向看,这意味着它将搜索不包含在匹配中的后缀。这个人再次寻找空白。
(?! )
否定前瞻-我想您到此为止,它的功能与上一个完全相同,但被否定了。当然,不包括在决赛中。
最后,您可以使用
\d+(?= )(?!\()
同样,以您提供的示例为例,但这取决于字符串的格式。
编辑: QHarr告诉我,VBA在先行方面非常合算,但它支持先行。我正在从
更改解决方案(?<!\()(?<= )\d+(?= )(?!\()
TO
\d+(?= )(?!\()
EDIT2 :
我再次从
更改了解决方案\d+(?= )(?!\()
TO
\d+(?!\()
由于罗恩·罗森菲尔德(Ron Rosenfeld)的建议,该解决方案的通用性不足以“匹配没有括号的第一个炸弹”。问题是,它不能匹配字符串末尾的数字,因为积极向前寻找空间。
答案 2 :(得分:0)
在非标准条件下设计正则表达式模式只获得了有限的成功,但是在实际的正则表达式模式匹配之前删除不想要的内容比取得合理的成功要好。
Function freeNums(str As String)
Dim i As Long
Static rgx As Object
'prep a return error if no match
freeNums = CVErr(xlErrNA)
'only create the object if it has never been used before
If rgx Is Nothing Then
Set rgx = CreateObject("VBScript.RegExp")
End If
'deal with the root string first and remove what we don't want to match
'pattern for 0-9 one to nine digits in length enclosed in brackets
rgx.Pattern = "\([0-9]{1,9}\)"
'numbers in brackets removed
str = rgx.Replace(str, vbNullString)
'now look for what we actually want
'pattern for 0-9 one to nine digits in length
rgx.Pattern = "[0-9]{1,9}"
If rgx.Test(str) Then
freeNums = rgx.Execute(str).Item(0)
End If
End Function
请注意,要保留前导零,结果将作为文本返回。文本的默认左对齐证明了这一点。最终,最好将结果返回为真数字并将单元格的格式设置为00000
。