Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式捕获后面几行的字符串_Regex_Powershell - Fatal编程技术网

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多个对象在一个循环中),我想这与较大字符串中正则表达式的性能有关