С учетом этого ввода ...
$testRecords = [Ordered] @{
0 = "@{}"; # No values
1 = "@{DekId=1}"; # Single value
2 = "@{DekId=1+1=2}" # Single value with equal sign
10 = "@{ }"; # No values (with padding)
11 = "@{ DekId=1 }"; # Single value (with padding)
12 = "@{ DekId=1+1=2 }" # Single value with equal sign (with padding)
# +------------------+--------------------+----------------+
# | Separating space | Trailing semicolon | Trailing space |
# +------------------+--------------------+----------------+
100 = "@{First=A B C;Second=X Y Z}"; # | No | No | No |
101 = "@{First=A B C;Second=X Y Z }"; # | No | No | Yes |
102 = "@{First=A B C;Second=X Y Z;}"; # | No | Yes | No |
103 = "@{First=A B C;Second=X Y Z; }"; # | No | Yes | Yes |
104 = "@{First=A B C; Second=X Y Z}"; # | Yes | No | No |
105 = "@{First=A B C; Second=X Y Z }"; # | Yes | No | Yes |
106 = "@{First=A B C; Second=X Y Z;}"; # | Yes | Yes | No |
107 = "@{First=A B C; Second=X Y Z; }"; # | Yes | Yes | Yes |
# First property empty # +------------------+--------------------+----------------+
200 = "@{First=;Second=X Y Z}"; # | No | No | No |
201 = "@{First=;Second=X Y Z }"; # | No | No | Yes |
202 = "@{First=;Second=X Y Z;}"; # | No | Yes | No |
203 = "@{First=;Second=X Y Z; }"; # | No | Yes | Yes |
204 = "@{First=; Second=X Y Z}"; # | Yes | No | No |
205 = "@{First=; Second=X Y Z }"; # | Yes | No | Yes |
206 = "@{First=; Second=X Y Z;}"; # | Yes | Yes | No |
207 = "@{First=; Second=X Y Z; }"; # | Yes | Yes | Yes |
# Second property empty # +------------------+--------------------+----------------+
300 = "@{First=A B C;Second=}"; # | No | No | No |
301 = "@{First=A B C;Second= }"; # | No | No | Yes |
302 = "@{First=A B C;Second=;}"; # | No | Yes | No |
303 = "@{First=A B C;Second=; }"; # | No | Yes | Yes |
304 = "@{First=A B C; Second=}"; # | Yes | No | No |
305 = "@{First=A B C; Second= }"; # | Yes | No | Yes |
306 = "@{First=A B C; Second=;}"; # | Yes | Yes | No |
307 = "@{First=A B C; Second=; }"; # | Yes | Yes | Yes |
# +------------------+--------------------+----------------+
7068 = "@{DekId=; FieldId=1234; OriginalValue=; NewValue=1234}";
7602 = "@{DekId=; FieldId=7602; OriginalValue=; NewValue=Alice, Hamburgler}";
}
... следующее использует регулярные выражения для извлечения окружающего @{ }
, а затем разбивает строку для анализа того, что внутри, в [Ordered]
hashtable instances ...
foreach ($pair in $testRecords.GetEnumerator())
{
Write-Host '=================================================='
if ($pair.Value -notmatch '@{\s*(?<Body>.*)\s*}')
{
Write-Warning "Pattern failed to match input ""$($pair.Value)""."
}
else
{
$properties = [Ordered] @{}
$bodyText = $Matches['Body']
if (-not [String]::IsNullOrWhiteSpace($bodyText))
{
foreach ($propertyText in $bodyText -split ';\s*')
{
# In case the property value contains an equal sign, split
# on only the first =, producing a two-element array
$propertyName, $propertyValue = $propertyText -split '=', 2
if (-not [String]::IsNullOrEmpty($propertyName))
{
$properties[$propertyName] = $propertyValue
}
}
}
Write-Host "Parsed input ""$($pair.Value)"" to $($properties.GetType().Name) with Count = $($properties.Count)"
$properties.GetEnumerator() `
| Select-Object -Property `
'Name', `
'Value', `
@{
Name = 'PrintableValue';
Expression = {
return $(
if ($_.Value -eq $null) {
'<null>'
} elseif ($_.Value.Length -eq 0) {
'<empty>'
} else {
$_.Value -replace '\s', [Char] 0x00B7 # Middle dot
}
)
};
} `
| Out-Host
}
}
Это дает следующий вывод ...
==================================================
Parsed input "@{}" to OrderedDictionary with Count = 0
==================================================
Parsed input "@{DekId=1}" to OrderedDictionary with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1 1
==================================================
Parsed input "@{DekId=1+1=2}" to OrderedDictionary with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1+1=2 1+1=2
==================================================
Parsed input "@{ }" to OrderedDictionary with Count = 0
==================================================
Parsed input "@{ DekId=1 }" to OrderedDictionary with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1 1·
==================================================
Parsed input "@{ DekId=1+1=2 }" to OrderedDictionary with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1+1=2 1+1=2·
==================================================
Parsed input "@{First=A B C;Second=X Y Z}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C;Second=X Y Z }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z·
==================================================
Parsed input "@{First=A B C;Second=X Y Z;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C;Second=X Y Z; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C; Second=X Y Z}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C; Second=X Y Z }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z·
==================================================
Parsed input "@{First=A B C; Second=X Y Z;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C; Second=X Y Z; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=;Second=X Y Z}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=;Second=X Y Z }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z·
==================================================
Parsed input "@{First=;Second=X Y Z;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=;Second=X Y Z; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=; Second=X Y Z}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=; Second=X Y Z }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z·
==================================================
Parsed input "@{First=; Second=X Y Z;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=; Second=X Y Z; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First <empty>
Second X Y Z X·Y·Z
==================================================
Parsed input "@{First=A B C;Second=}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{First=A B C;Second= }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second ·
==================================================
Parsed input "@{First=A B C;Second=;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{First=A B C;Second=; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{First=A B C; Second=}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{First=A B C; Second= }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second ·
==================================================
Parsed input "@{First=A B C; Second=;}" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{First=A B C; Second=; }" to OrderedDictionary with Count = 2
Name Value PrintableValue
---- ----- --------------
First A B C A·B·C
Second <empty>
==================================================
Parsed input "@{DekId=; FieldId=1234; OriginalValue=; NewValue=1234}" to OrderedDictionary with Count = 4
Name Value PrintableValue
---- ----- --------------
DekId <empty>
FieldId 1234 1234
OriginalValue <empty>
NewValue 1234 1234
==================================================
Parsed input "@{DekId=; FieldId=7602; OriginalValue=; NewValue=Alice, Hamburgler}" to OrderedDictionary with Count = 4
Name Value PrintableValue
---- ----- --------------
DekId <empty>
FieldId 7602 7602
OriginalValue <empty>
NewValue Alice, Hamburgler Alice,·Hamburgler
Обратите внимание, что из-за жадного квантификатора 1015 *, используемого в Body
group (то есть (?<Body>.*)
), в случае, когда у последнего свойства есть завершающий пробел, но нет конечной точки с запятой, этот пробел будет включен в значение свойства. Если такое поведение нежелательно, вы можете изменить его на ленивый квантификатор (например, (?<Body>.*?)
).
Я разбил все в упорядоченные хеш-таблицы / словари, чтобы было проще сопоставить входной текст с выходными свойствами, но вы также можете использовать обычный Hashtable
.
В качестве альтернативы вы можете использовать оператор -replace
, чтобы превратить введенный текст в действительный PowerShell Hashtable
синтаксис , добавляя кавычки вокруг совпадающих значений свойств ...
# Match the shortest text possible between "Name=" and a ";" or
# a "}" and replace it with that same text surrounded by quotes
$replacementText = $originalText -replace '(?<=[a-z]+=)(?<Value>.*?)(?=;|\s*})', '"${Value}"'
... и затем используйте Invoke-Expression
командлет для его анализа в Hashtable
экземпляр ...
$properties = Invoke-Expression -Command $replacementText
В этом регулярном выражении предполагается, что ...
- Все значения свойств требуют кавычек.
- Никакие значения свойств не содержат символов
;
или }
.
Используя тот же ввод, что и выше, следующий код ...
foreach ($pair in $testRecords.GetEnumerator())
{
Write-Host '=================================================='
$originalText = $pair.Value
Write-Host " Original text: $originalText"
# Match the shortest text possible between "Name=" and a ";" or
# a "}" and replace it with that same text surrounded by quotes
$replacementText = $originalText -replace '(?<=[a-z]+=)(?<Value>.*?)(?=;|\s*})', '"${Value}"'
if ([Object]::ReferenceEquals($originalText, $replacementText))
{
Write-Host 'Replacement text is indentical to original text'
}
else
{
Write-Host "Replacement text: $replacementText";
}
$properties = Invoke-Expression -Command $replacementText
Write-Host "Replacement text evaluated to $($properties.GetType().Name) with Count = $($properties.Count)"
$properties.GetEnumerator() `
| Select-Object -Property `
'Name', `
'Value', `
@{
Name = 'PrintableValue';
Expression = {
return $(
if ($_.Value -eq $null) {
'<null>'
} elseif ($_.Value.Length -eq 0) {
'<empty>'
} else {
$_.Value -replace '\s', [Char] 0x00B7 # Middle dot
}
)
};
} `
| Out-Host
}
.. . производит этот вывод ...
==================================================
Original text: @{}
Replacement text is indentical to original text
Replacement text evaluated to Hashtable with Count = 0
==================================================
Original text: @{DekId=1}
Replacement text: @{DekId="1"}
Replacement text evaluated to Hashtable with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1 1
==================================================
Original text: @{DekId=1+1=2}
Replacement text: @{DekId="1+1=2"}
Replacement text evaluated to Hashtable with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1+1=2 1+1=2
==================================================
Original text: @{ }
Replacement text is indentical to original text
Replacement text evaluated to Hashtable with Count = 0
==================================================
Original text: @{ DekId=1 }
Replacement text: @{ DekId="1" }
Replacement text evaluated to Hashtable with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1 1
==================================================
Original text: @{ DekId=1+1=2 }
Replacement text: @{ DekId="1+1=2" }
Replacement text evaluated to Hashtable with Count = 1
Name Value PrintableValue
---- ----- --------------
DekId 1+1=2 1+1=2
==================================================
Original text: @{First=A B C;Second=X Y Z}
Replacement text: @{First="A B C";Second="X Y Z"}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second=X Y Z }
Replacement text: @{First="A B C";Second="X Y Z" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second=X Y Z;}
Replacement text: @{First="A B C";Second="X Y Z";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second=X Y Z; }
Replacement text: @{First="A B C";Second="X Y Z"; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=X Y Z}
Replacement text: @{First="A B C"; Second="X Y Z"}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=X Y Z }
Replacement text: @{First="A B C"; Second="X Y Z" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=X Y Z;}
Replacement text: @{First="A B C"; Second="X Y Z";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=X Y Z; }
Replacement text: @{First="A B C"; Second="X Y Z"; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First A B C A·B·C
==================================================
Original text: @{First=;Second=X Y Z}
Replacement text: @{First="";Second="X Y Z"}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=;Second=X Y Z }
Replacement text: @{First="";Second="X Y Z" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=;Second=X Y Z;}
Replacement text: @{First="";Second="X Y Z";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=;Second=X Y Z; }
Replacement text: @{First="";Second="X Y Z"; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=; Second=X Y Z}
Replacement text: @{First=""; Second="X Y Z"}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=; Second=X Y Z }
Replacement text: @{First=""; Second="X Y Z" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=; Second=X Y Z;}
Replacement text: @{First=""; Second="X Y Z";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=; Second=X Y Z; }
Replacement text: @{First=""; Second="X Y Z"; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second X Y Z X·Y·Z
First <empty>
==================================================
Original text: @{First=A B C;Second=}
Replacement text: @{First="A B C";Second=""}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second= }
Replacement text: @{First="A B C";Second="" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second=;}
Replacement text: @{First="A B C";Second="";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C;Second=; }
Replacement text: @{First="A B C";Second=""; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=}
Replacement text: @{First="A B C"; Second=""}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second= }
Replacement text: @{First="A B C"; Second="" }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=;}
Replacement text: @{First="A B C"; Second="";}
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{First=A B C; Second=; }
Replacement text: @{First="A B C"; Second=""; }
Replacement text evaluated to Hashtable with Count = 2
Name Value PrintableValue
---- ----- --------------
Second <empty>
First A B C A·B·C
==================================================
Original text: @{DekId=; FieldId=1234; OriginalValue=; NewValue=1234}
Replacement text: @{DekId=""; FieldId="1234"; OriginalValue=""; NewValue="1234"}
Replacement text evaluated to Hashtable with Count = 4
Name Value PrintableValue
---- ----- --------------
NewValue 1234 1234
OriginalValue <empty>
DekId <empty>
FieldId 1234 1234
==================================================
Original text: @{DekId=; FieldId=7602; OriginalValue=; NewValue=Alice, Hamburgler}
Replacement text: @{DekId=""; FieldId="7602"; OriginalValue=""; NewValue="Alice, Hamburgler"}
Replacement text evaluated to Hashtable with Count = 4
Name Value PrintableValue
---- ----- --------------
NewValue Alice, Hamburgler Alice,·Hamburgler
OriginalValue <empty>
DekId <empty>
FieldId 7602 7602