Regex 正则表达式捕获后面几行的字符串
我正在尝试为以下示例文本创建捕获:Regex 正则表达式捕获后面几行的字符串,regex,powershell,Regex,Powershell,我正在尝试为以下示例文本创建捕获: object-group network og-n-sna-EWB-UAT-srvrs-4 network-object host 10.34.68.108 network-object host 10.34.68.109 network-object host 10.34.68.110 object-group network og-n-bng-ind-users network-object object obj-FAIBLR04L1025 ne
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
现在,我正试图找出如何捕获对象组(og-n-bng-ind-users)的名称,对象obj-FAIBLR04L1344是其中的一部分。
我试过组合*\snetwork object\sobject\sobj-FAIBLR04L1344*
后面看了看,但我无法让它工作。有人知道如何构造这个正则表达式来使用PowerShell吗?您确定要在这里使用正则表达式吗
准备:
$text = @'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@
$networkObjectId = 'obj-FAIBLR04L1344' + [System.Environment]::NewLine
变体:
$objectGroupListFound = @($text.Split([string[]]@('object-group'), [System.StringSplitOptions]::RemoveEmptyEntries) |
Where-Object { $_.Contains( "network-object object $($networkObjectId)" ) } |
ForEach-Object { $_.Split([System.Environment]::NewLine)[0]} |
ForEach-Object { $_.Split()[-1]} )
if ($objectGroupListFound.Count -ne 1)
{
Write-Error "No objectGroup found for networkObjectId $($networkObjectId) or found more than one. Found $($objectGroupListFound.Count)."
}
## There I omit "else", assuming code upper is wrapped into try block and on error, it will not reach this line.
$objectGroup = $objectGroupListFound[0]
$tempText = $text.Substring(0,$text.IndexOf($networkObjectId))
$tempText = $tempText.Substring($tempText.LastIndexOf('object-group'))
$objectGroup = $tempText.Split("`r`n".ToCharArray(), [System.StringSplitOptions]::RemoveEmptyEntries)[0].Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[2]
变体:
$objectGroupListFound = @($text.Split([string[]]@('object-group'), [System.StringSplitOptions]::RemoveEmptyEntries) |
Where-Object { $_.Contains( "network-object object $($networkObjectId)" ) } |
ForEach-Object { $_.Split([System.Environment]::NewLine)[0]} |
ForEach-Object { $_.Split()[-1]} )
if ($objectGroupListFound.Count -ne 1)
{
Write-Error "No objectGroup found for networkObjectId $($networkObjectId) or found more than one. Found $($objectGroupListFound.Count)."
}
## There I omit "else", assuming code upper is wrapped into try block and on error, it will not reach this line.
$objectGroup = $objectGroupListFound[0]
$tempText = $text.Substring(0,$text.IndexOf($networkObjectId))
$tempText = $tempText.Substring($tempText.LastIndexOf('object-group'))
$objectGroup = $tempText.Split("`r`n".ToCharArray(), [System.StringSplitOptions]::RemoveEmptyEntries)[0].Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[2]
变体(逐行)-我认为它是最简单和清楚的
$text = [System.IO.File]::ReadAllLines($path)
# or $text = $text.Split([char[]]"`r`n", [System.StringSplitOptions]::RemoveEmptyEntries)
$networkObjectId = "obj-FAIBLR04L1344"
$objectGroupCache = $null
$objectGroup = $null
for ($i = 0; $i -lt $text.Count; $i++)
{
if ($text[$i].Trim().StartsWith('object-group network'))
{
# We are entering this group.
$objectGroupCache =$text[$i].Split([char[]]" `t", [System.StringSplitOptions]::RemoveEmptyEntries)[-1]
}
elseif ($text[$i].Trim().StartsWith('network-object') -and $text[$i].Trim().EndsWith($networkObjectId))
{
$objectGroup = $objectGroupCache
break;
}
}
if ([String]::IsNullOrWhiteSpace($objectGroup))
{
Write-Error "Not found"
}
假设文本存储在
text.txt
中,我相信这是可行的:
Get Content-Raw text.txt|
选择字符串`
-所有匹配`
-模式'(?另一种方法是使用ConvertFrom字符串。这适用于小样本数据。很可能模板需要更多的“训练”数据。它所基于的是惊人的
$template = @'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network {Name: og-n-bng-ind-users}
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@
@'
object-group network og-n-sna-EWB-UAT-srvrs-4
network-object host 10.34.68.108
network-object host 10.34.68.109
network-object host 10.34.68.110
object-group network og-n-bng-ind-users
network-object object obj-FAIBLR04L1025
network-object object obj-FAIBLR04L1741
network-object object obj-FAIBLR04L1344
network-object object obj-FAIBLR04L1193
network-object object obj-FAIBLR06L1318
object-group network og-n-mdm-srvrs-7
network-object host 10.36.50.101
network-object host 10.36.50.102
'@ | ConvertFrom-String -TemplateContent $template
或者从一个文件
Get-Content $file | ConvertFrom-String -TemplateContent $template
Name
----
og-n-bng-ind-users
您还可以选择将整个文件解析为PSObject数组,这样不仅可以方便地获取所需的任何项目,还可以将文件保存为CSV文件,以便在Excel中使用
$result = switch -Regex -File 'D:\Test\thefile.txt' {
'^object-group network ' { $group = ($_.Trim() -split '\s')[-1] }
'network-object' {
$item = $_.Trim() -split '\s'
[PsCustomObject]@{
Group = $group
Type = $item[1]
Value = $item[2]
}
}
}
一旦将此文件转换为对象数组,就可以获得任何内容
您需要从中获取,如值“obj-FAIBLR04L1344”的对象组名称
($result | Where-Object { $_.Value -eq 'obj-FAIBLR04L1344' }).Group # --> og-n-bng-ind-users
PowerShell使用类似PCRE的正则表达式,因此它不应该与其他语言有太大区别。在.NET中,正则表达式模式由一种特殊的语法或语言定义,该语法或语言与Perl 5正则表达式兼容,并添加了一些附加功能,如从右向左匹配。您不需要查找,可以使用cap在组^对象组网络(\S+(>\r?\n(?!对象组网络)。*)*\r?\n.*obj-FAIBLR04L1344
为什么'obj-FAIBLR04L1344'+[System.Environment]::NewLine
而不仅仅是“obj-faibl04l1344`n”
?@NekoMusume,1)因为我猜,$networkObjectId
可能是某些循环中的一个变量。2) 在Windows上,它应该是'r'n,而不是'n'<代码>换行符
保留默认操作系统换行符序列。根据文件和方法的不同,它可以给我“$($var)`r`n”或“$($var)`n”谢谢@filimonic。在我的200.000多个大样本中,它工作得很好,性能也不错lines@MartinWJørgensen如果需要对同一文件进行一次性
查找,最好使用glogg
文本查看器(仅64位)。它为文本文件编制索引,几乎可以在线搜索,并在几秒钟内打开超过2 GB的文件。@这一个在一个小样本中工作,但在我的完整配置中,有超过200.000行的文本,只需运行其中一个对象(我有3000多个对象在一个循环中),我想这与较大字符串中正则表达式的性能有关