如何在一个regex对象中使用多个模式?
我用如何在一个regex对象中使用多个模式?,regex,vba,excel,web-scraping,Regex,Vba,Excel,Web Scraping,我用vba和正则表达式编写了一个脚本,从网页上解析公司名称、电话和传真。当我运行脚本时,我完美地获得了这些信息。然而,问题是我使用了三个不同的表达式,为了使它们成功运行,我创建了三个不同的regex对象,如rxp、rxp1和rxp2 我的问题:如何创建一个regex对象,在其中我将能够使用三种模式,这与我下面所做的不同 这是脚本(工作脚本): 要添加到库以执行上述脚本的引用: Microsoft XML, v6.0 Microsoft VBScript Regular Expressions
vba
和正则表达式
编写了一个脚本,从网页上解析公司名称
、电话
和传真
。当我运行脚本时,我完美地获得了这些信息。然而,问题是我使用了三个不同的表达式
,为了使它们成功运行,我创建了三个不同的regex对象
,如rxp
、rxp1
和rxp2
我的问题:如何创建一个regex对象
,在其中我将能够使用三种模式
,这与我下面所做的不同
这是脚本(工作脚本):
要添加到库以执行上述脚本的引用:
Microsoft XML, v6.0
Microsoft VBScript Regular Expressions
公司名称:\s*(.*)\n?电话:\s*(.*)\n?传真:\s*(.*)\n?
将其捕获为三个捕获组。你可以看到它是如何工作的
第1组是您的公司名称,第2组是您的电话号码,第3组是您的传真。您可以构建一个带有替代项的正则表达式,启用与
rxp.global=True
的全局匹配,并将已知字符串捕获到第1组中,将未知部分捕获到第2组中。然后,通过检查组1的值,您将能够为变量分配正确的值:
Const Url$ = "https://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736"
Dim rxp As New RegExp
Dim ms As MatchCollection
Dim m As Match
Dim cname As String, phone As String, fax As String
With New XMLHTTP60
.Open "GET", Url, False
.send
rxp.Pattern = "(Phone|Company Name|Fax):\s*(\+?[\w\s]*\w)"
rxp.Global = True
Set ms = rxp.Execute(.responseText)
For Each m In ms
If m.SubMatches(0) = "Company Name" Then cname = m.SubMatches(1)
If m.SubMatches(0) = "Phone" Then phone = m.SubMatches(1)
If m.SubMatches(0) = "Fax" Then fax = m.SubMatches(1)
Next
Debug.Print cname, phone, fax
End With
输出:
Vaucraft Braford Stud +61 7 4942 4859 +61 7 4942 0618
看
图案细节:
-捕获组1:三种备选方案中的任意一种(电话|公司名称|传真)
-一个冒号,然后是0+空格:\s*
-捕获组2:(\+?[\w\s]*\w)
-可选的\+?
+
-0个或多个字母、数字、[\w\s]*
或空格\u
-单个字母、数字或\w
\u
- 你可以做到,但我不确定这是否是个好主意。合并regexp将使其更容易出现问题/错误
如果同时匹配所有3个数据,则所有都必须存在,否则regexp将失败。甚至更糟糕的是,它将获取错误的数据。如果传真是可选字段,会发生什么情况?有关示例,请参见
此外,如果web模板发生变化,则更容易破坏内容。假设模板改变,传真在电话前呈现:整个regexp将失败,因为一次搜索3个数据意味着某种顺序
除非您正在搜索的数据相互关联或相互依赖,否则我不会选择这条路线。我认为以下内容可以帮助您完成同样的任务,只要声明
rxp
:
Sub GetInfo()
Const Url$ = "https://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736"
Dim Http As New XMLHTTP60, rxp As New RegExp
With Http
.Open "GET", Url, False
.send
End With
With rxp
.Pattern = "Company Name:(\s[\w\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[A1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Phone:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[B1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Fax:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[C1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
End With
End Sub
提供一些示例数据将为您提供更好的答案。在没有看到布局的情况下,我们只是猜测如何组合模式。脚本@emsimpson92中已经提供了一个链接。您是否尝试过或regex sytax组合成一个模式字符串?公司名称:(\s[\w\s]+)|电话:(\s\+[\d\s]+)|传真:(\s\+[\d\s]+)作为您的模式?谢谢您的评论@QHarr。我知道如何将它们组合成一种模式。用例是什么?再一次,这里不关心模式。我的问题是如何使用它们在一个regex对象中获得三个不同的结果。谢谢。它们将在一个单一的正则表达式对象中。当存在任何与正则表达式相关的问题时,您在@Wiktor Stribiżew中是首屈一指的。感谢一万亿美元。一个小问题:为什么子匹配变成1而不是0?请原谅我的无知。@Topto第一个捕获组-
。SubMatches(0)
-包含已知值,我们可以通过该值识别匹配字符串的类型。我们想知道的值在组2中,。子匹配(1)
。
Sub GetInfo()
Const Url$ = "https://www.austrade.gov.au/SupplierDetails.aspx?ORGID=ORG0120000508&folderid=1736"
Dim Http As New XMLHTTP60, rxp As New RegExp
With Http
.Open "GET", Url, False
.send
End With
With rxp
.Pattern = "Company Name:(\s[\w\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[A1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Phone:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[B1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
.Pattern = "Fax:(\s\+[\d\s]+)"
If .Execute(Http.responseText).Count > 0 Then
[C1] = .Execute(Http.responseText)(0).SubMatches(0)
End If
End With
End Sub