无法仅捕获两个引号之一
Unable to capture just one of two quotes
所以我正在处理 this blog post 以尝试解析 ini
文件。它在大多数情况下都有效,但我 运行 遇到了一个具体问题,我对 regex
了解不够,无法解决。
代码示例:
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
'^"(.*)"$', '' -replace
'\s*(.*)\s*', ''
}
}
$ini
}
}
问题:
本节内容:
$ini[$section][$Matches['Key']] = $Matches['Value'] -replace
'^"(.*)"$','' -replace
'\s*(.*)\s*',''
我 运行 遇到以下情况:我的 ini
文件可能包含引号值,然后包含带引号的字符串:
Key=" this value="something here""
我想要一个正则表达式字符串(最好在开关捕获中)以避免周围的双引号。
我尝试在值的两边使用可选字符 "?
,但它只能跳过起始引号,而不是结束引号。
编辑
示例字符串:
KeyName = "value:"ac-dii-sk""
尝试的模式:
$HashPattern = '\s*(?<Key>.+)\s*=\s*"?\s*(?<Value>.*)\s*"?\s*'
结果:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk""
想要的结果:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk"
让我们尝试一下 Balancing Capture Groups。
(?<Key>.+?)\s*=\s*(?<open>")?(?<Value>.*?)(?<close-open>")?$
Test it Online
输入:KeyName = "value:"ac-dii-sk""
捕获值:value:"ac-dii-sk"
输入:KeyName = "value:"ac-dii-sk"
(少了 1 个结束引号)
值:value:"ac-dii-sk
输入:KeyName = value:"ac-dii-sk""
(缺少开头引号)
值:value:"ac-dii-sk""
输入:KeyName = value:"ac-dii-sk"
(没有引号)
值:value:"ac-dii-sk"
正如我在评论中提到的,我建议您只使用现有的库来解析 INI 文件。这里有 2 个来自 PSGallery:
所以我正在处理 this blog post 以尝试解析 ini
文件。它在大多数情况下都有效,但我 运行 遇到了一个具体问题,我对 regex
了解不够,无法解决。
代码示例:
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
'^"(.*)"$', '' -replace
'\s*(.*)\s*', ''
}
}
$ini
}
}
问题:
本节内容:
$ini[$section][$Matches['Key']] = $Matches['Value'] -replace
'^"(.*)"$','' -replace
'\s*(.*)\s*',''
我 运行 遇到以下情况:我的 ini
文件可能包含引号值,然后包含带引号的字符串:
Key=" this value="something here""
我想要一个正则表达式字符串(最好在开关捕获中)以避免周围的双引号。
我尝试在值的两边使用可选字符 "?
,但它只能跳过起始引号,而不是结束引号。
编辑
示例字符串:
KeyName = "value:"ac-dii-sk""
尝试的模式:
$HashPattern = '\s*(?<Key>.+)\s*=\s*"?\s*(?<Value>.*)\s*"?\s*'
结果:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk""
想要的结果:
$Matches['Key'] = KeyName
$Matches['Value'] = value:"ac-dii-sk"
让我们尝试一下 Balancing Capture Groups。
(?<Key>.+?)\s*=\s*(?<open>")?(?<Value>.*?)(?<close-open>")?$
Test it Online
输入:KeyName = "value:"ac-dii-sk""
捕获值:value:"ac-dii-sk"
输入:KeyName = "value:"ac-dii-sk"
(少了 1 个结束引号)
值:value:"ac-dii-sk
输入:KeyName = value:"ac-dii-sk""
(缺少开头引号)
值:value:"ac-dii-sk""
输入:KeyName = value:"ac-dii-sk"
(没有引号)
值:value:"ac-dii-sk"
正如我在评论中提到的,我建议您只使用现有的库来解析 INI 文件。这里有 2 个来自 PSGallery: