问题
So I'm working off of this blog post in an attempt to parse ini
files. It works for the most part, but I'm running into a specific problem I don't know enough about regex
to solve.
Code sample:
function Get-IniContent
{
[CmdletBinding()]
[OutputType([hashtable])]
param
(
[Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName)]
[ValidateScript({Test-Path -Path $PSItem -PathType Leaf})]
[Alias('FullName')]
[string]
$Path
)
process
{
$ini = @{}
switch -Regex -File $Path
{
'^\[(?<Section>.+)\]$'
{
$section = $Matches['Section']
$ini[$section] = @{}
$commentCount = 0
}
'^;(?<Comment>.*)'
{
if (-not $section)
{
$section = 'NoSection'
$ini[$section] = @{}
}
$commentCount += 1
$ini[$section]["Comment$commentCount"] = $Matches['Comment']
}
'(?<Key>.+?)\s*=\s*(?<Value>.*)'
{
if (-not $section)
{
$section = 'NoSection'
$ini[$section] = @{}
}
$ini[$section][$Matches['Key']] = $Matches['Value'] -replace
'^"(.*)"$', '$1' -replace
'\s*(.*)\s*', '$1'
}
}
$ini
}
}
The problem:
In this section:
$ini[$section][$Matches['Key']] = $Matches['Value'] -replace
'^"(.*)"$','$1' -replace
'\s*(.*)\s*','$1'
I'm running into cases where my ini
files may have quoted values that then have strings with quotes:
Key=" this value="something here""
I want a single regex string (ideally in the switch capture) to avoid those surrounding double-quotes.
I tried using the optional character "?
around both sides of the value, but it only managed to skip the starting quote, but not the ending quote.
Edit
Sample string:
KeyName = "value:"ac-dii-sk""
Attempted pattern:
$HashPattern = '\s*(?<Key>.+)\s*=\s*"?\s*(?<Value>.*)\s*"?\s*'
Results:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk""
Desired results:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk"
回答1:
Let's give it a try with Balancing Capture Groups.
(?<Key>.+?)\s*=\s*(?<open>")?(?<Value>.*?)(?<close-open>")?$
Test it Online
Input: KeyName = "value:"ac-dii-sk""
Captured Value: value:"ac-dii-sk"
Input: KeyName = "value:"ac-dii-sk"
(1 fewer end quote)
Value: value:"ac-dii-sk
Input: KeyName = value:"ac-dii-sk""
(missing beginning quote)
Value: value:"ac-dii-sk""
Input: KeyName = value:"ac-dii-sk"
(no surrounding quotes)
Value: value:"ac-dii-sk"
As I mentioned in a comment, I recommend you just use an existing library to parse INI files. Here are 2 from PSGallery:
- Carbon
- PsIni
来源:https://stackoverflow.com/questions/47948012/unable-to-capture-just-one-of-two-quotes