正则表达式非捕获组
Regex non capturing group
正则表达式专家。
我需要一些帮助来从下面的 HTML 字符串中捕获 IP 地址及其状态。
$html = "<div><br> Active Zone : BW Zone 1[1], VIP = 192.168.254.10</div>
<div><br> <a href=https://192.168.254.10/checkGlobalReplicationTier>https://192.168.254.10/checkGlobalReplicationTier</a>
[ACTIVE]</div>
<div> <a href=https://192.168.254.10/checkReplication>https://192.168.254.10/checkReplication</a></div>
<div><br> <a href=https://192.168.254.11/checkGlobalReplicationTier>https://192.168.254.11/checkGlobalReplicationTier</a>
[STANDBY]</div>
<div> <a href=https://192.168.254.11/checkReplication>https://192.168.254.11/checkReplication</a></div>
<div><br> Local Zones:</div>
<div> LC Zone 3[3], VIP = 192.168.254.13
<div> <a href=https://192.168.254.13/checkReplication>https://192.168.254.13/checkReplication</a>
[ACTIVE]</div>"
[regex]::matches($html, '((\d{1,3}\.){3}\d{1,3})((?s).*?)((?<=\[)[A-z]*(?=\]))').value
上面的正则表达式能够获取 IP 和状态..但我想省略 IP 和状态之间的所有内容。我如何使用非捕获正则表达式执行此操作。
192.168.254.10 Active
192.168.254.11 Standby
192.168.254.13 Active
一般是a bad idea to attempt to parse HTML with regular expressions.
而是使用专用的 HTML 解析器作为 uri 的 HtmlDocument class (and the Uri class。
例子
function ParseHtml($String) {
$Unicode = [System.Text.Encoding]::Unicode.GetBytes($String)
$Html = New-Object -Com 'HTMLFile'
if ($Html.PSObject.Methods.Name -Contains 'IHTMLDocument2_Write') {
$Html.IHTMLDocument2_Write($Unicode)
}
else {
$Html.write($Unicode)
}
$Html.Close()
$Html
}
$Document = ParseHtml $Html
$Document.getElementsByTagName('div') |ForEach-Object {
if ($_.lastChild.nodeValue -match '\[(?<Status>ACTIVE|STANDBY)\]') {
[pscustomobject]@{
Ip = ([Uri]$($_.getElementsByTagName('a')).href).Host
Status = $Matches.Status
}
}
}
Ip Status
-- ------
192.168.254.10 ACTIVE
192.168.254.11 STANDBY
192.168.254.13 ACTIVE
通常,考虑 使用专用解析器进行稳健的 HTML 解析。
How do i do this with non capturing regex.
你不能,因为为了排除部分匹配的文本范围,你需要 look-around 断言(例如你尝试中的否定 look-behind 断言,例如 (?<=\[)
),但这些反过来会阻止您消耗跨度中不需要的部分。
而是使用两个捕获组并按如下方式访问它们:
[regex]::Matches(
$html,
'(?s)((?:\d{1,3}\.){3}\d{1,3}).+?\[([A-Z]+)\]'
) | ForEach-Object {
[pscustomobject] @{
Ip = $_.Groups[1].Value
Status = $_.Groups[2].Value
}
}
这导致以下显示输出:
Ip Status
-- ------
192.168.254.10 ACTIVE
192.168.254.11 STANDBY
192.168.254.13 ACTIVE
正则表达式专家。 我需要一些帮助来从下面的 HTML 字符串中捕获 IP 地址及其状态。
$html = "<div><br> Active Zone : BW Zone 1[1], VIP = 192.168.254.10</div>
<div><br> <a href=https://192.168.254.10/checkGlobalReplicationTier>https://192.168.254.10/checkGlobalReplicationTier</a>
[ACTIVE]</div>
<div> <a href=https://192.168.254.10/checkReplication>https://192.168.254.10/checkReplication</a></div>
<div><br> <a href=https://192.168.254.11/checkGlobalReplicationTier>https://192.168.254.11/checkGlobalReplicationTier</a>
[STANDBY]</div>
<div> <a href=https://192.168.254.11/checkReplication>https://192.168.254.11/checkReplication</a></div>
<div><br> Local Zones:</div>
<div> LC Zone 3[3], VIP = 192.168.254.13
<div> <a href=https://192.168.254.13/checkReplication>https://192.168.254.13/checkReplication</a>
[ACTIVE]</div>"
[regex]::matches($html, '((\d{1,3}\.){3}\d{1,3})((?s).*?)((?<=\[)[A-z]*(?=\]))').value
上面的正则表达式能够获取 IP 和状态..但我想省略 IP 和状态之间的所有内容。我如何使用非捕获正则表达式执行此操作。
192.168.254.10 Active
192.168.254.11 Standby
192.168.254.13 Active
一般是a bad idea to attempt to parse HTML with regular expressions.
而是使用专用的 HTML 解析器作为 uri 的 HtmlDocument class (and the Uri class。
例子
function ParseHtml($String) {
$Unicode = [System.Text.Encoding]::Unicode.GetBytes($String)
$Html = New-Object -Com 'HTMLFile'
if ($Html.PSObject.Methods.Name -Contains 'IHTMLDocument2_Write') {
$Html.IHTMLDocument2_Write($Unicode)
}
else {
$Html.write($Unicode)
}
$Html.Close()
$Html
}
$Document = ParseHtml $Html
$Document.getElementsByTagName('div') |ForEach-Object {
if ($_.lastChild.nodeValue -match '\[(?<Status>ACTIVE|STANDBY)\]') {
[pscustomobject]@{
Ip = ([Uri]$($_.getElementsByTagName('a')).href).Host
Status = $Matches.Status
}
}
}
Ip Status
-- ------
192.168.254.10 ACTIVE
192.168.254.11 STANDBY
192.168.254.13 ACTIVE
通常,考虑
How do i do this with non capturing regex.
你不能,因为为了排除部分匹配的文本范围,你需要 look-around 断言(例如你尝试中的否定 look-behind 断言,例如 (?<=\[)
),但这些反过来会阻止您消耗跨度中不需要的部分。
而是使用两个捕获组并按如下方式访问它们:
[regex]::Matches(
$html,
'(?s)((?:\d{1,3}\.){3}\d{1,3}).+?\[([A-Z]+)\]'
) | ForEach-Object {
[pscustomobject] @{
Ip = $_.Groups[1].Value
Status = $_.Groups[2].Value
}
}
这导致以下显示输出:
Ip Status
-- ------
192.168.254.10 ACTIVE
192.168.254.11 STANDBY
192.168.254.13 ACTIVE