【问题标题】:regex with wildcards in the middle of a string字符串中间带有通配符的正则表达式
【发布时间】:2021-02-05 04:47:23
【问题描述】:

我有大量来自不同用户的 [HKEY_CURRENT_USER\Printers\Connections] 注册表导出。 此文件包含多行带有“

[HKEY_CURRENT_USER\Printers\Connections\,,BBPRINTER01.domain.local,AG-printer-S4]

我需要 BBPRINTER01.domain.local,AG-printer-S4 部分。问题是,BBPRINTER01AG-printer-S4 可能不同。

所以我需要一个正则表达式,它从[HKEY_CURRENT_USER\Printers\Connections\,,BBPRINTER01.domain.local,AG-printer-S4] 中提取“.domain.local,”。

而且我没有任何线索来生成这个:(

使用(?<=\[)(.*)(?=\]) 我可以获得包括[] 在内的所有内容,但我不知道如何仅从上面获取通配符字符串。

【问题讨论】:

  • 问题不完全清楚,你想在 `HKEY_CURRENT_USER\Printers\Connections` 之后的方括号内找到所有可能的值吗?因此,例如 [HKEY_CURRENT_USER\Printers\Connections\,,A,B] 字符串 'A,B' ?
  • @Panciz 很清楚:OP 寻求的值在括号之间,最后,以一些单词字符和 .domain.local 开始,直到结束 ]

标签: regex string powershell wildcard


【解决方案1】:

如果你需要从一个文件夹中的多个文件中解析这个,你可以使用

$files = Get-ChildItem -Path 'Path\To\The\Files' -File
foreach ($file in $files) {
    Get-Content -Path $file.FullName | 
    Select-String -Pattern '\[.*,([^,]+,[^\]]+)\]' -AllMatches | 
    ForEach-Object { $_.Matches.Groups[1].Value }
}

正则表达式详细信息

\[              Match the character “[” literally
    .           Match any single character
   *            Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
,               Match the character “,” literally
(               Match the regex below and capture its match into backreference number 1
   [^,]         Match any character that is NOT a “,”
      +         Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   ,            Match the character “,” literally
   [^\]]        Match any character that is NOT a “]”
      +         Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)              
\]              Match the character “]” literally

结果可能类似于

BBPRINTER01.domain.local,AG-printer-S4
BBPRINTER02.otherdomain.local,AG-printer-S5
BBPRINTER03.somedomain.local,AG-printer-S6

编辑

根据您的评论,要输出文件路径和正则表达式匹配,最简洁的方法是输出 objects 而不是字符串,并将这些结果捕获到变量中。使用对象,您还有机会写入可以在 Excel 中打开的结构化 CSV 文件:

$files  = Get-ChildItem -Path 'Path\To\The\Files' -File
$result = foreach ($file in $files) {
    Get-Content -Path $file.FullName | 
    Select-String -Pattern '\[.*,([^,]+,[^\]]+)\]' -AllMatches | 
    ForEach-Object { 
        [PsCustomObject]@{
            'SourceFile'   = $file.FullName
            'Regex-Output' = $_.Matches.Groups[1].Value 
        }
    }
}

# output on screen
$result | Format-Table -AutoSize

# write to CSV file
$result | Export-Csv -Path 'Path\To\The\result.csv' -UseCulture -NoTypeInformation

【讨论】:

  • @horst 很高兴它对你有用。如果您觉得我的回答解决了您的问题,请考虑点击左侧的✓ 接受回答。见How to accept SO answers。这将帮助其他有类似问题的人更轻松地找到它。
  • 我标记了正确答案;最后一个问题,我如何从“ForEach-Object { Write-Output $_.Matches.Groups[1].Value | Out-File $Results -Append}”得到类似“sourcefilename,regex-output”的输出“在结果文件中?目前我只得到结果文件中每行的“regex-output”行;
  • @horst 谢谢。请参阅我的编辑,它应该让您了解如何输出到对象数组
  • 效果很好!再次感谢您的帮助!
  • 我将 "'SourceFile' = $file.FullName" 更改为 "'SourceFile' = $file.BaseName" 因为我只有输出文件中的纯文件名,没有完整路径和文件扩展;
【解决方案2】:

您可以使用以下方法将子字符串捕获到第 1 组中

\[[^][]*?(\w+\.domain\.local,[^][]*)]

this regex demo。它匹配

  • \[ - 一个 [ 字符
  • [^][]*? - 除了[] 之外,0+ 字符尽可能少
  • ( - 捕获组 1 的开始
  • \w+ - 一个或多个字母/数字/_
  • \.domain\.local, - .domain.local, 字符串
  • [^\]\[]* - 除了 ][ 之外的 0 个或多个字符
  • )捕获组结束
  • ] - ] 字符。

在 PowerShell 中,使用

$result = Get-Content $file | Select-String -Pattern '\w+\.domain\.local,[^][]*'
if ($result.Matches.Success) { $result.Matches.Groups[1].Value }
# => BBPRINTER01.domain.local,AG-printer-S4

PowerShell 测试:

【讨论】:

  • 非常感谢,该模式在测试仪中运行良好!但是当我尝试通过 Get-Content $file | 调用模式时选择字符串-模式 '\w+\.domain\.local,[^][]*' |选择 -Expand Line 我得到 [] 之间的整个字符串,而不仅仅是过滤后的字符串
  • @horst 您需要将结果分配给类型为MatchInfo 的变量,然后,您只需访问其Group 1 值。我更新了答案。
  • 新的正则表达式字符串似乎不再正确,因为我不再在正则表达式测试中得到任何结果,并且 powershell 给了我这个结果:+ $result.Matches.Groups[ 1].Value + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : 空数组
  • @horst 查看截图。您指定的文件中似乎没有任何匹配项。
  • 我认为问题在于,我在 foreach 循环中调用函数,因为我有很多文件,我想解析:foreach ($file in $files) { $result = 获取内容 $file | Select-String -Pattern '[[^][]*?(\w+\.domain\.local,[^][]*)]' $result.Matches.Groups[1].Value }
猜你喜欢
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多