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



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

我的变量:在Data前面:DeviceAddresses":[{"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文本:

$ ( ) * + . ? [  ^ { |

此外,#(常规空格字符(需要转义,并且许多其他空白字符必须转换为它们各自的转义序列,以使模式可以安全地与IgnorePatternWhitespace选项一起使用(这不适用于您当前的场景(:

u0009 => 't'   # Tab
u000A => 'n'   # Line Feed
u000C => 'f'   # Form Feed
u000D => 'r'   # Carriage Return

Regex.Escape()为您考虑的所有因素:(

补充Mathias R.Jessen的有用答案:

一般来说,请注意,如果将JSON数据解析为可以访问其属性的对象,则该数据更容易处理,处理也更稳健-请参阅底部的部分

至于您的正则表达式尝试

  • 注意:以下内容也适用于所有PowerShell本机正则表达式功能,如-match-replace-split运算符、switch语句和Select-Stringcmdlet。

  • Mathias的答案使用[regex]::Escape()转义正则表达式引擎将逐字使用的正则表达式模式部分。

    • 如果这些逐字部分事先不知道,例如,通过变量或表达式提供,或作为参数传递时,这无疑是的最佳方法
  • 但是,在指定为字符串literal正则表达式模式中,通常更容易单独-转义正则表达式元字符,即那些对正则表达式引擎具有特殊意义的字符。

    • 需要转义的字符列表为(可以从.NET正则表达式快速参考中推断出(:
      • ( ) | . * + ? ^ $ [ {
      • 如果启用了IgnorePatternWhiteSpace选项(可以在模式开始时与
        (?x)内联(,则还必须执行-escape:
        • #
        • 逐字指定的重要空白字符(您实际想要匹配的字符((例如,' ',或通过字符串插值,"`t"(;这不适用于通过转义序列指定的那些(例如tn(

因此,该解决方案可以简化为:

# Sample JSON
$changeduserdata = '{"DeviceAddresses":[{"Id": 42,"More": "stuff"}]}'
# Note how [ and { are -escaped
$deviceId = if ($changeduserdata -match 'DeviceAddresses":[{"Id":(.*?),"') {
$Matches[1]
}

使用ConvertFrom-Json将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

最新更新