VBA正则表达式模式组合匹配和不匹配模式

时间:2016-10-16 00:27:50

标签: regex excel-vba match vba excel

尝试从字符串中提取有效的电话号码,不同数据类型之间没有可见的分隔符。实际上,潜在电话号码周围的数据是随机的,不相关的。


应该匹配什么。我想尝试匹配以下任一项:

  • [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的参考资料足够了: - )

1 个答案:

答案 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

结果( 原样,然后又一次;虽然课程有时可能会改变 ):

Screenshot from Excel showing the input un column A and the result of the function in column B