如果没有一些真实(模拟)数据,我认为最好不要使用正则表达式。此外,这可以通过将其视为 CSV 来大大简化。
首先进行此测试,其他人也可以尝试,我们将制作一个示例文件
$tempfile = New-TemporaryFile
$data = @'
1111 xxxx yyyyyyyyyyyyyyyy 2222 zzzz wwwwwww
3333 aaaa bbbbbbbbbbbbbbbb 4444 cccc ddddddd
'@ | Set-Content $tempfile -Encoding utf8
接下来,我们在用逗号替换空格的同时读取信息。如果您的数据有空格,那么这当然需要调整或不使用,具体取决于。
(Get-Content $tempfile) -replace '\s+',','
1111,xxxx,yyyyyyyyyyyyyyyy,2222,zzzz,wwwwwww
3333,aaaa,bbbbbbbbbbbbbbbb,4444,cccc,ddddddd
现在我们知道我们的数据是正确的,在指定标题的同时导入为 CSV。你可以提供有意义的标题,因为你知道信息是什么。
(Get-Content $tempfile) -replace '\s+',',' | ConvertFrom-Csv -Header a,b,c,d,e,f
a : 1111
b : xxxx
c : yyyyyyyyyyyyyyyy
d : 2222
e : zzzz
f : wwwwwww
a : 3333
b : aaaa
c : bbbbbbbbbbbbbbbb
d : 4444
e : cccc
f : ddddddd
如果您只想要某些列,只需选择那些。
(Get-Content $tempfile) -replace '\s+',',' |
ConvertFrom-Csv -Header a,b,c,d,e,f | Select b,c,e,f -OutVariale data
b c e f
- - - -
xxxx yyyyyyyyyyyyyyyy zzzz wwwwwww
aaaa bbbbbbbbbbbbbbbb cccc ddddddd
现在相应地分配它
$data | select b,e -OutVariable data1
b e
- -
xxxx zzzz
aaaa cccc
$data | select c,f -OutVariable data2
c f
- -
yyyyyyyyyyyyyyyy wwwwwww
bbbbbbbbbbbbbbbb ddddddd
编辑
您的有意义的数据改变了我的建议。也很好奇额外的列在哪里,因为它不像你最初显示的那样。根据您显示的数据,我有三种不同的选择。
再次,从一些示例数据开始
$tempfile = New-TemporaryFile
@'
Car 1FMZU77E22UC18440 Honda CiviC
Car SCBCR63W55C024793 GM Colorado
Truck SZXYR63W55C165487 GM some model
'@ | Set-Content $tempfile -Encoding utf8
选项 1 - ConvertFrom-String
ConvertFrom-String 可以根据您作为“训练”数据提供的模板解析数据。
$template = @'
{Type*:abc} {VIN:ABCDEFGH123456789} {Model:some model}
{Type*:abcde} {VIN:sample} {Model:a some model}
'@
现在我们应用模板。使其逐行优于正则表达式的一方面是您可以使用快速的 -Raw 参数获取内容,这非常快。
get-content $tempfile -Raw |
ConvertFrom-String -TemplateContent $template -OutVariable data
Type VIN Model
---- --- -----
Car 1FMZU77E22UC18440 Honda CiviC
Car SCBCR63W55C024793 GM Colorado
Truck SZXYR63W55C165487 GM some model
如果您不需要该类型,请忽略它。将其设置为您的变量,例如
$data1,$data2 = $data.vin,$data.model
变量$data1和$data2的内容
$data2
Honda CiviC
GM Colorado
GM some model
$data1
1FMZU77E22UC18440
SCBCR63W55C024793
SZXYR63W55C165487
选项 2 - 正则表达式获取内容/逐行
Get-Content $tempfile | foreach {
if($_ -match '(?<=[\s]{3})(\w*)[\s]{5}(.*)$')
{
[PSCustomObject]@{
Model = $matches.2
VIN = $matches.1
}
}
}
再次根据需要设置变量
$data1,$data2 = $data.vin,$data.model
选项 3 - Select-String(可能更接近选项 1 的速度)
Select-String -path $tempfile -Pattern '(?<=[\s]{3})(\w*)[\s]{5}(.+)' -AllMatches | ForEach {
$_.Matches | foreach {
[PSCustomObject]@{
Model = $_.groups[2].value
VIN = $_.groups[1].value
}
}
} -OutVariable data