methuselah
methuselah

Reputation: 13216

Use regex in Powershell v2 to get values from a json file

How would I access the following values using the regex function in Powershell, and assign each one to an individual variable?:

id (i.e. get the value: TOKEN_ID) - under token

id (i.e. get the value: TENANT_ID) - under token, tenant

adminURL (i.e. get the value: http://10.100.0.222:35357/v2.0) - the first value under serviceCatalog,endpoints

As I am using Powershell v2, I can't use the ConvertFrom-Json cmdlet. So far I've tried converting the document to an xml file using the a third-party PS script, but it doesn't always get it right. I'd like to use regex, but I am not very comfortable with it.

$json =
    "{
        "access": {
            "metadata": {
                "is_admin": 0,
                "roles": [
                    "9fe2ff9ee4384b1894a90878d3e92bab"
                ]
            },
            "serviceCatalog": [
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8774/v2/TENANT_ID",
                            "id": "0eb78b6d3f644438aea327d9c57b7b5a",
                            "internalURL": "http://10.100.0.222:8774/v2/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8774/v2/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "nova",
                    "type": "compute"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:9696/",
                            "id": "3f4b6015a2f9481481ca03dace8acf32",
                            "internalURL": "http://10.100.0.222:9696/",
                            "publicURL": "http://8.21.28.222:9696/",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "neutron",
                    "type": "network"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8776/v2/TENANT_ID",
                            "id": "16f6416588f64946bdcdf4a431a8f252",
                            "internalURL": "http://10.100.0.222:8776/v2/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8776/v2/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "cinder_v2",
                    "type": "volumev2"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8779/v1.0/TENANT_ID",
                            "id": "be48765ae31e425cb06036b1ebab694a",
                            "internalURL": "http://10.100.0.222:8779/v1.0/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8779/v1.0/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "trove",
                    "type": "database"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:9292",
                            "id": "1adfcb5414304f3596fb81edb2dfb514",
                            "internalURL": "http://10.100.0.222:9292",
                            "publicURL": "http://8.21.28.222:9292",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "glance",
                    "type": "image"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8777",
                            "id": "350f3b91d73f4b3ab8a061c94ac31fbb",
                            "internalURL": "http://10.100.0.222:8777",
                            "publicURL": "http://8.21.28.222:8777",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "ceilometer",
                    "type": "metering"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8000/v1/",
                            "id": "2198b0d32a604e75a5cc1e13276a813d",
                            "internalURL": "http://10.100.0.222:8000/v1/",
                            "publicURL": "http://8.21.28.222:8000/v1/",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "heat-cfn",
                    "type": "cloudformation"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8776/v1/TENANT_ID",
                            "id": "7c193c4683d849ca8e8db493722a4d8c",
                            "internalURL": "http://10.100.0.222:8776/v1/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8776/v1/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "cinder",
                    "type": "volume"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8773/services/Admin",
                            "id": "11fac8254be74d7d906110f0069e5748",
                            "internalURL": "http://10.100.0.222:8773/services/Cloud",
                            "publicURL": "http://8.21.28.222:8773/services/Cloud",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "nova_ec2",
                    "type": "ec2"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8004/v1/TENANT_ID",
                            "id": "38fa4f9afce34d4ca0f5e0f90fd758dd",
                            "internalURL": "http://10.100.0.222:8004/v1/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8004/v1/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "heat",
                    "type": "orchestration"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:35357/v2.0",
                            "id": "256cdf78ecb04051bf0f57ec11070222",
                            "internalURL": "http://10.100.0.222:5000/v2.0",
                            "publicURL": "http://8.21.28.222:5000/v2.0",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "keystone",
                    "type": "identity"
                }
            ],
            "token": {
                "audit_ids": [
                    "gsjrNoqFSQeuLUo0QeJprQ"
                ],
                "expires": "2014-12-15T15:09:29Z",
                "id": "TOKEN_ID",
                "issued_at": "2014-12-15T14:09:29.794527",
                "tenant": {
                    "description": "Auto created account",
                    "enabled": true,
                    "id": "TENANT_ID",
                    "name": "USERNAME"
                }
            },
            "user": {
                "id": "USER_ID",
                "name": "USERNAME",
                "roles": [
                    {
                        "name": "_member_"
                    }
                ],
                "roles_links": [],
                "username": "USERNAME"
            }
        }
    }"

Upvotes: 2

Views: 1819

Answers (1)

briantist
briantist

Reputation: 47862

If you are using .NET 3.5 or higher on your machines with PowerShell 2.0, you can use a JSON serializer (from the linked answer):

[System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$json = "{a:1,b:2,c:{nested:true}}"
$ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$obj = $ser.DeserializeObject($json)

This would be preferable to using regex.

For admin URL for example, you'd refer to:

$obj.access.serviceCatalog[0].endpoints[0].adminURL

Using RegEx Anyway

if ($json -match '(?s)"serviceCatalog".+?"endpoints".+?"adminURL"[^"]+"(?<adminUrl>[^"]+)".+?"token".+?"id"[^"]+"(?<tokenID>[^"]+)".+?"tenant".+?"id"[^"]+"(?<tenantID>[^"]+)') {
    $Matches['adminURL']
    $Matches['tokenID']
    $Matches['tenantID']
}

RegEx Breakdown:

  • (?s) tells the regex engine that . matches anything, including newlines (by default it wouldn't).
  • Of course all of the "whatever" parts just match literally.
  • .+? matches 1 or more of any character (including newlines since we're using s), and the ? makes it non-greedy.
  • [^"]+ this matches 1 or more characters that are not a double quote.
  • () is a capturing group. By using (?<name>) we can refer back to the group later by name rather than number, just a nicety.

So the basic idea is to look for the literals, then get to a point where we can capture the values needed. After a -regex operator match in PowerShell, the $Matches variable is populated with the matches, groups, etc.

Note that this relies on the values being in the order they are in the posted JSON. If they were in a different order it would fail.

To work around that you could split this into 3 different regex matches.

Upvotes: 3

Related Questions