Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我需要从两个变量(Powershell)之间的一行json数据中提取数据_Json_Regex_Powershell - Fatal编程技术网

我需要从两个变量(Powershell)之间的一行json数据中提取数据

我需要从两个变量(Powershell)之间的一行json数据中提取数据,json,regex,powershell,Json,Regex,Powershell,我需要从两个变量(Powershell)之间的一行json数据中提取数据 我的变量: 在数据前面: 设备地址“:[{“Id”: 数据之后: " 我尝试了这个,但由于我使用的所有特殊字符,需要出现一些错误: $devicepattern = {DeviceAddresses":[{"Id":{.*?},"} #$deviceid = [regex]::match($changeduserdata, $devicepattern).Groups[1].Valu

我需要从两个变量(Powershell)之间的一行json数据中提取数据

我的变量: 在数据前面: 设备地址“:[{“Id”: 数据之后: "

我尝试了这个,但由于我使用的所有特殊字符,需要出现一些错误:

$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