我需要从两个变量(Powershell)之间的一行json数据中提取数据
我需要从两个变量(Powershell)之间的一行json数据中提取数据 我的变量: 在数据前面: 设备地址“:[{“Id”: 数据之后: " 我尝试了这个,但由于我使用的所有特殊字符,需要出现一些错误:我需要从两个变量(Powershell)之间的一行json数据中提取数据,json,regex,powershell,Json,Regex,Powershell,我需要从两个变量(Powershell)之间的一行json数据中提取数据 我的变量: 在数据前面: 设备地址“:[{“Id”: 数据之后: " 我尝试了这个,但由于我使用的所有特殊字符,需要出现一些错误: $devicepattern = {DeviceAddresses":[{"Id":{.*?},"} #$deviceid = [regex]::match($changeduserdata, $devicepattern).Groups[1].Valu
$devicepattern = {DeviceAddresses":[{"Id":{.*?},"}
#$deviceid = [regex]::match($changeduserdata, $devicepattern).Groups[1].Value
#$deviceid
正如您所发现的,一些字符文字不能像在正则表达式模式中那样使用,因为它们具有特殊的含义——我们称之为元字符 为了匹配输入字符串中相应的字符文字,我们需要使用
\
-
- 为了匹配文本
),我们使用转义序列(
)\(
- 对于文本
,我们使用}
,依此类推\}
Regex.Escape()
转义给定模式字符串中的所有特殊字符:
$prefix = [regex]::Escape('DeviceAddresses":[{"Id":')
$capture = '(.*?)'
$suffix = [regex]::Escape(',"')
$devicePattern = "${prefix}${capture}${suffix}"
您也不需要直接调用[regex]::Match
,只要标量-Match
成功,PowerShell就会用匹配组填充自动$Matches
变量:
if($changeduserdata -match $devicePattern){
$deviceid = $Matches[1]
} else {
Write-Error 'DeviceID not found'
}
作为参考,需要在.NET的正则表达式语法中转义以下ASCII文本:
$ ( ) * + . ? [ \ ^ { |
此外,#
和
(常规空格字符)需要转义,并且必须将许多其他空白字符转换为各自的转义序列,以使模式安全地用于(这不适用于当前场景):
…所有这些Regex.Escape()
都会为您考虑:)以补充:
一般来说,请注意,如果将JSON数据解析为可以访问其属性的对象,那么它就更容易使用,处理起来也更可靠。请参见底部部分
至于您的正则表达式尝试:
- Mathias的答案使用来逐字转义正则表达式引擎要使用的正则表达式模式部分
- 如果这些逐字部分事先不知道,这无疑是最好的方法,例如,通过变量或表达式提供,或作为参数传递
- 但是,在指定为字符串文本的正则表达式模式中,通常更容易单独
-转义正则表达式元字符,即那些对正则表达式引擎具有特殊意义的字符\
- 需要转义的字符的列表是(可以从中推断):
\()|。*+?^$[{
- 如果您启用(您可以通过内联方式执行)
,在模式开始时),您还必须(?x)
-转义:\
#
- 重要空白字符(您实际希望匹配的)按原样指定(例如,
,或通过字符串插值,'
);这不适用于通过转义序列指定的字符(例如,'`t
或\t
)\n
- 需要转义的字符的列表是(可以从中推断):
# Sample JSON
$changeduserdata = '{"DeviceAddresses":[{"Id": 42,"More": "stuff"}]}'
# Note how [ and { are \-escaped
$deviceId = if ($changeduserdata -match 'DeviceAddresses":\[\{"Id":(.*?),"') {
$Matches[1]
}
使用将JSON正确解析到对象中更健壮、更方便,因为它允许属性访问(点表示法)提取感兴趣的值:
# Sample JSON
$changeduserdata = '{"DeviceAddresses":[{"Id": 42,"More": "stuff"}]}'
# Convert to an object ([pscustomobject]) and drill down to the property
# of interest; note that the value of .DeviceAddresses is an *array* ([...]).
$deviceId = (ConvertFrom-Json $changeduserdata).DeviceAddresses[0].Id # -> 42
请注意,如果您将JSON数据解析为可以访问其属性的对象,那么处理JSON数据会容易得多-请参阅。理解,并感谢您在回答中的澄清。由于我们处于困境,一个诡辩(仅此而已):您仍然不需要使用
IgnorePatternWhitespace
(尽管我同意这样做更好):\
-转义逐字空白字符也有效:“a`tb”-match”(?x)a\`tb”
# Sample JSON
$changeduserdata = '{"DeviceAddresses":[{"Id": 42,"More": "stuff"}]}'
# Convert to an object ([pscustomobject]) and drill down to the property
# of interest; note that the value of .DeviceAddresses is an *array* ([...]).
$deviceId = (ConvertFrom-Json $changeduserdata).DeviceAddresses[0].Id # -> 42