目前我正在嘗試從 Microsoft 站點(它的 GitHub 版本)決議一個表以獲取正確的 PowerShell 物件。我將分享相關的代碼部分,以便您進行測驗。它確實決議了我想要的內容,但我希望結果已經被修剪(沒有前導尾隨空格或換行符)。我還必須獲得具有不同格式的“CNG Key Isolation”的結果。僅對于該資料塊,我的 RegEx 包含換行符,但我沒有讓它作業。我知道我可以在 RegEx 之后在 PowerShell 中進行一些決議,但我希望使用 RegEx 做得更好。
我尚未優化的 RegEx 看起來像這樣
(?:^##\s*(?<ServiceTitle>[^\r\n#]*)[\r\n\s]*\|\s Name\s \|\s Description\s \|(?:[\r\n\s\|\-\*] Service name[\|\*\s] (?<ServiceName>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Description[\|\*\s] (?<Description>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Installation[\|\*\s] (?<Installation>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Startup type[\|\*\s] (?<StartupType>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Recommendation[\|\*\s] (?<Recommendation>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Comments[\|\*\s] (?<Comments>[^\|]*?)(?: ?\|))*)
你可以在這里測驗它:https ://regex101.com/r/xQDRCO/1
要決議的資料來自:https ://raw.githubusercontent.com/MicrosoftDocs/windowsserverdocs/main/WindowsServerDocs/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server.md
它基本上應該為每個服務獲取一個資料塊并嘗試獲取
"ServiceTitle","ServiceName","Description","Installation","StartupType","Recommendation","Comments"
無論它們是什么順序,或者是否缺少其中之一。“ServiceTitle”是特別的東西,必須在那里。
這是我目前測驗的 PowerShell 代碼:
$fields = "ServiceTitle","ServiceName","Description","Installation","StartupType","Recommendation","Comments"
$RequestData = Invoke-WebRequest -UseBasicParsing -Uri https://raw.githubusercontent.com/MicrosoftDocs/windowsserverdocs/main/WindowsServerDocs/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server.md
$RegExMatches = [Regex]::Matches($RequestData.content,'(?:^##\s*(?<ServiceTitle>[^\r\n#]*)[\r\n\s]*\|\s Name\s \|\s Description\s \|(?:[\r\n\s\|\-\*] Service name[\|\*\s] (?<ServiceName>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Description[\|\*\s] (?<Description>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Installation[\|\*\s] (?<Installation>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Startup type[\|\*\s] (?<StartupType>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Recommendation[\|\*\s] (?<Recommendation>[^\|]*?)(?: ?\|)|[\r\n\s\|\-\*] Comments[\|\*\s] (?<Comments>[^\|]*?)(?: ?\|))*)',[System.Text.RegularExpressions.RegexOptions]::Multiline)
$FullList = @()
foreach ($entry in $RegExMatches) {$ServiceAsObject = [pscustomobject]@{};foreach ($field in $fields) {$ServiceAsObject | Add-Member -MemberType NoteProperty -Name $field -Value $entry.Groups[$field].value};$FullList = $ServiceAsObject}
$FullList[15..17] # three items to see what problem i have with "CNG Key Isolation"
我不經常使用較大的 RegEx,所以請隨時給我一些反饋以改進自己。
謝謝你,安迪爾
uj5u.com熱心網友回復:
這可能不是您要查找的內容,但您可以執行以下操作來輸出自定義物件陣列:
$output = switch -regex ($requestdata.content -split '\r?\n') {
'^##\s' {
# tracking empty lines since there is one under the service title
# start new hash table when a new service is found
# remove ## from service title names
$emptyLineCount = 0
$hash = [ordered]@{}
$hash.ServiceTitle = $_ -replace '^##\s'
}
'\| \*\*' {
# split on | and surrounding spaces
# replace ** so name is cleaner
if ($hash.ServiceTitle) {
$key,$value = ($_ -split '\s*\|\s*' -replace '\*\*')[1,2]
$hash[$key] = $value
}
}
'^$' {
# when second empty line is reached in a service block, output object
if ($hash.ServiceTitle -and $emptyLineCount -eq 2) {
[pscustomobject]$hash
}
}
}
# Finding a service by title
$output | Where ServiceTitle -eq 'CNG Key Isolation'
拆分內容會產生一個行陣列,這對我來說更容易使用switch陳述句。
如果存在資料不一致,使用更純粹的正則運算式解決方案會使事情變得更加脆弱。CNG Key Isolation 的資料塊 |在每一行的末尾都丟失了,并且是唯一一個這樣的資料塊。所以現在你必須匹配那個特殊情況或修復資料。
$fields = "ServiceTitle","ServiceName","Description","Installation","StartupType","Recommendation","Comments"
$RequestData = Invoke-WebRequest -UseBasicParsing -Uri https://raw.githubusercontent.com/MicrosoftDocs/windowsserverdocs/main/WindowsServerDocs/security/windows-services/security-guidelines-for-disabling-system-services-in-windows-server.md
$regexString = '(?m)^##\s(?<ServiceTitle>.*)$(?s).*?\*\*Service name\*\* \| (?<ServiceName>.*?(?=\s \|)).*?\*\*Description\*\* \| (?<Description>.*?(?=\s \|)).*?\*\*Installation\*\* \| (?<Installation>.*?(?=\s \|)).*?\*\*Startup type\*\* \| (?<StartupType>.*?(?=\s \|)).*?\*\*Recommendation\*\* \| (?<Recommendation>.*?(?=\s \|)).*?\*\*Comments\*\* \| (?<Comments>.*?(?=\s \|))'
$out = $RequestData.Content |
Select-String -Pattern $regexString -AllMatches |
Foreach-Object { $_.Matches | Foreach-Object {
$hash = [ordered]@{}
foreach ($field in $fields) {
$hash.$field = $_.Groups.where{$_.Name -eq $field}.Value}
[pscustomobject]$hash
}
}
uj5u.com熱心網友回復:
假設您的 中包含所有文本$RequestData.content,那么我不會嘗試創建一個大型正則運算式來將其全部決議為可用物件,而是會這樣做:
# first split the tables from the rest of the text and work on the table lines only
$result = ($RequestData.content -split '(?m)^The following tables.*:')[-1].Trim() -split '(?m)^## ' |
Where-Object { $_ -match '\S' } |
ForEach-Object {
# split each block to parse out the title and the table data
$title, $table = ($_.Trim() -split '(\r?\n){2}', 2).Trim()
# now remove the markdown stuff from the data and convert it using ConvertFrom-Csv
$data = (($table -replace '(?m)^\|--\|--\||[*]{2}|^\||\|$' -replace '\s\|\s', '|') -split '\r?\n' -ne '').Trim() | ConvertFrom-Csv -Delimiter '|'
# set up an ordered Hashtable to store the data
$hash = [ordered]@{ServiceTitle = $title}
foreach ($item in $data) {
$hash[$item.Name] = $item.Description
}
# output real objects
[PsCustomObject]$hash
}
$result
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/411036.html
標籤:
