【问题标题】:Powershell Regex: Reading a multi-line string between two pointsPowershell Regex:读取两点之间的多行字符串
【发布时间】:2015-01-14 12:19:23
【问题描述】:

我有一个使用 powershell 正则表达式来读取多行记录的常见问题。我已经阅读了询问类似问题的线程,但无法完全让解决方案在我的情况下起作用。

我的文件由可变长度的多行记录组成。我感兴趣的记录以 01 或 02 开头,后跟 V 或 M。每当另一个记录开始或找到以“50”开头的批次记录时,记录就会结束。每行的前三个字符标识记录。

即 01V(记录开始 - 内容如下) 01

我正在尝试通过识别开始和结束来使用正则表达式读取各个记录。

我目前所拥有的是基于这个答案: Match everything between two words in Powershell

#Read the file as a single string
$FilePath = "blaablaablaa"
$TestFile = get-content $FilePath | Out-String 

#( ?= Assert that this matches before the current position
# 0(1|2)(V|M) if the record is 01V or 01M or 02V or 02M 
# ) End assertion 
# .+? Match any number of characters, few as possible
# (?= Until a record starting with 70 is found  
# ) End of look ahead
$regex = [regex] '(?is)(?<=0(1|2)(V|M)).+?(?=70)'
echo $TestFile |  select-string -Pattern $regex 

如果我删除管道以使用 out-string 管道返回整个文件,则上述内容将适用于单行字符串。我猜我没有正确处理 /n 字符。

有什么建议吗?输入文件大致如下:

00 日期
01Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01 01 01 01=0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01=5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01 01 01 01=0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01=9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
50 xxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx
01Vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$A xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$B 0xxxxxxxxxxxxxxxxxxxx
01$0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
50 xxxxxxxxxxxx BatchTotal
90 xxxxxxxxxxxx FILETotal

所需的输出是将文件拆分为单独的记录,这些记录由“50”或“90”或另一条记录的开头分隔。例如,这是最终记录:-

01Vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$A xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$B 0xxxxxxxxxxxxxxxxxxxx
01$0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$5xxxxxxxxxxxxxxxxxxxxxxxxxxx

【问题讨论】:

  • 您能否提供一个示例以及预期输出?
  • 您的描述和示例不匹配。有一个 01Mxxx 行,您将其描述为想要匹配但从您想要的示例中排除。您谈到以50 开头的行来结束匹配,您的代码注释说它将搜索直到找到70,但是您的示例在遇到71 时结束。同样,该示例不包含01^ 作为第二行,它会立即转到01$
  • 抱歉,我编辑了示例以使其更清晰。基本上,如果一条线以 01V 或 01M 开头,我想捕获所有内容,直到遇到另一条以 01V 或 01M 或 50 或 90 开头的线。

标签: regex powershell


【解决方案1】:

假设(根据您的描述)您还想匹配从01M 到下一个01M 的部分,然后分别匹配到50。这样就可以了:

(?gmis)^0[12][VM](?:[^\n]|\n(?!0[12][VM]|50|90))+

说明:匹配0, 1 2, V M后,(?:...)中的部分是这样的:

[^\n]|\n(?!0[12][VM]|50|90)

这意味着:

匹配任何不是换行符的字符

换行符不跟随 (?!...) 新记录的开头 50 90 em>。

online Regex101 demo

【讨论】:

  • 在 Regex101 演示中完美运行。但是当我在我的powershell脚本中使用它时,它只返回像“01Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”这样的单行,而不是完整的多行记录。如果我通过输出字符串管道我的文件,它会再次返回整个文件。一定是关于 /n 字符抛出正则表达式的东西。
【解决方案2】:

使用您的测试数据:

@'
00 date
01Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01 01 01 01=0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01=5xxxxxxxxxxxxxxxxxxxxxxxxxxx
01Mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01 01 01 01=0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01=9xxxxxxxxxxxxxxxxxxxxxxxxxxx
50 xxxxxxxxxxxxx xxxxxxxxxxxxxxxxx
01Vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$A xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$B 0xxxxxxxxxxxxxxxxxxxx
01$0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$5xxxxxxxxxxxxxxxxxxxxxxxxxxx
50 xxxxxxxxxxxx BatchTotal
90 xxxxxxxxxxxx FILETotal
'@ | set-content testfile.txt


$Text = Get-Content ./testfile.txt -Raw

$regex = @'
(?ms)(01(?:M|V).+?)
(?:5|9)0.+?
'@


$Records = 
[regex]::Matches($Text,$regex) |
foreach {$_.groups[1].value}

$Records[-1]

01Vxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$A xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$B 0xxxxxxxxxxxxxxxxxxxx
01$0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
01$5xxxxxxxxxxxxxxxxxxxxxxxxxxx

【讨论】:

    猜你喜欢
    • 2015-05-10
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多