首页 > 解决方案 > Powershell匹配两个字符串之间的多行字符

问题描述

我无法弄清楚如何从日志文件中提取所有内容(多行)。这是我需要从中提取的样本:

FieldCoilConnectivity=00
ConfigError=readback radio section
NfcErrorCode=0

[compare Errors]

我只需要提取这部分:

readback radio section
NfcErrorCode=0

我正在使用带有此脚本的 powershell:

$input_path = ‘C:\Users\martin.kuracka\Desktop\temp\Analyza_chyb_SUEZ_CommTEst\022020\*_E.log’
$output_file = ‘C:\Users\martin.kuracka\Desktop\temp\Analyza_chyb_SUEZ_CommTEst\032020\extracted.txt’
$regex = ‘(?<=ConfigError=)(.*)(?=[compare Errors])’
select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file

但最终只有这样:

readback radio secti

甚至没有提取完整的第一行。你能帮我吗?

标签: regexpowershell

解决方案


有几个问题:

  • 您正在以逐行读取模式打开文件,您需要将文件作为单个变量读取(使用Get-Content $filepath -Raw
  • 您没有转义[,并且[compare Errors]被视为与集合中的单个字符匹配的字符类(您需要\[compare Errors]
  • 您需要一个RegexOptions.Singleline修饰符或(?s)内联选项来.匹配换行符
  • 您需要使用 non-greedy .*?,而不是.*在第一次出现时停止[compar e Errors]

利用

$regex = '(?s)(?<=ConfigError=).*?(?=\s*\[compare Errors])'
Get-Content $input_path -Raw | Select-String -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file

.*?请注意,由于您没有使用子匹配,因此我从周围删除了捕获括号,并且我\s*之前添加\[了以从尾随空格“修剪”结果匹配。

正则表达式详细信息

  • (?s)- 单行模式跨行.匹配
  • (?<=ConfigError=)- 紧接在前面的位置ConfigError
  • .*?- 任何 0 个或更多字符,尽可能少
  • (?=\s*\[compare Errors])- 紧靠右边,后面必须有 0+ 个空格[compare Errors]

推荐阅读