尝试从字符串中提取有效的电话号码,不同数据类型之间没有可见的分隔符。实际上,潜在电话号码周围的数据是随机的,不相关的。
应该匹配什么。我想尝试匹配以下任一项:
[random garbage][optional '1'][optional '(']###[optional')'[[random or no white space]###-####[random garbage]
或[random garbage]###[optional '-']###,[optional '-']####[random garbage]
仅使用第一个电话号码,因此我在下面的代码中使用了Global = False
。我可以使它更加强大,但我已经检查了数据,这应该足够了。
工作模式。这是一个函数的代码片段(它返回匹配的电话号码),其中包含有效的模式。
With regex
.Global = False
.Pattern = "1?(\(?\d{3}\)?\(s+)?|\d{3}-?)\d{3}-?\d{4}"
'this works but does detect an extension as explained above
End With
不应匹配的内容。我意识到我还需要搜索电话号码旁边的分机(即[phone number][white space]x#
)和(如果存在),将电话号码视为无效(.test
应该评价为假)。
尝试失败。它们都失败了(即使有效的电话号码.test
评估为假):
.Pattern = "1?(\(?\d{3}\)?\(s+)?|\d{3}-?)\d{3}-?\d{4}^(\s?x\d)"
'detect not([optional single white space]x#), added "^(\s?x\d)"
'or
.Pattern = "1?(\(?\d{3}\)?\(s+)?|\d{3}-?)\d{3}-?\d{4}^((\s+?)[x]\d)"
'detect not([optional multiple white space]x#), added "^((\s+?)[x]\d)"
不确定如何在同一模式中结合正匹配测试和否定(非)匹配测试。
我尝试过的解决方法。当我无法使其工作时,我尝试了以下Like
模式(使用VBA' Like',在调用使用Regexp的函数之前)并且也失败了(所有评估即使是包含"...1x2"
或"5 x33"
或"...7 x444"
等示例的测试字符串,也会显示为false;其中包含"*#x#*"
,"*#{ x}#*"
,""*#{ x}#*"
等模式。
以下是测试Like函数的代码片段:
If Not (OrigNum Like "*#x#" Or OrigNum Like "*#[ x}#" Or OrigNum Like "*#[ x]#*") Then
Debug.Print "No #x# in string"
OrigNum = ExtractPhoneNumber(OrigNum)
Else
Debug.Print "#x# in string"
End If
评估的每个字符串最终都会导致显示"No x# in string"
(评估为false),即使字符串包含上面的示例,它们应该已经评估为true并且显示"#x# in string"
。
长时间困惑和困惑......好了,Led Zepp的参考资料足够了: - )
答案 0 :(得分:1)
电话号码:
[optional '1'][optional '(']###[optional')'[[random or no white space]###-####
###[optional '-']###[optional '-']####
*我删除了一个我认为是拼写错误的逗号,并假设前导1
对于我从您的模式中读取的两种情况都是可选的。
不匹配:
[phone number][white space]x#
你要找的是negative lookaheads。
(?! subexpression )
从当前位置断言该子表达式,如果子表达式匹配,则匹配尝试失败(即后面没有)。
例如。当前位置后跟可选空格,“x”和数字时,(?!\s*x\d)
失败。
正则表达式:
1?(?:\(\d{3}\)|\d{3}-?)\s*\d{3}-?\d{4}(?!\s*x\d)
代码:
Public Function getPhoneNumber(strInput As String) As Variant
Dim regex As New RegExp
Dim matches As Object
regex.Pattern = "1?(?:\(\d{3}\)\s*|\d{3}-?)\d{3}-?\d{4}(?!\s*x\d)"
regex.Global = False
Set matches = regex.Execute(strInput)
If matches.Count = 0 Then
getPhoneNumber = CVErr(xlErrNA)
Else
getPhoneNumber = matches(0).Value
End If
End Function