user13800089
user13800089

Reputation:

Powershell - split string to array delineated by start and end strings

I have a multi-line string (from a json) like

"somekey": "somevalue",
"somekey": "somevalue"
"somekey": [somevalue]
"somekey": somenumber
"somekey": null,

I'd like to split the string into an array, where the value of each element is either the value of somevalue or somenumber. (I'm essentially forming an array containing the values of every value that appears in a json)

This should yield the following element values:

somevalue
somevalue
somevalue
somenumber

I've played with variations and additions to, the followning code:

$jsonValues = $jsonValues.Split(": ").Split([Environment]::NewLine)

but wondering about the most eloquent way to achieve this.

Upvotes: 1

Views: 268

Answers (2)

mklement0
mklement0

Reputation: 440616

Here's a function that generically extracts all leaf property values from a JSON document, using proper JSON parsing via ConvertFrom-Json:

# Accepts a JSON string and outputs all leaf property values.
function Get-JsonValue {
  param([Parameter(ValueFromPipeline)] $json)

  begin {
    # Helper function that walks the object graph.
    function walk {
      param($obj)

      # Note: @(...) is used so that scalar $null values aren't ignored.
      foreach ($elem in @($obj)) {
        if ($elem -isnot [System.Management.Automation.PSCustomObject]) { 
          $elem # leaf value -> output
        }
        else {
          # recurse
          foreach ($prop in $elem.psobject.Properties) {
            foreach ($subElem in @($prop.Value)) { walk $subElem }
          }
        }
      }
    }
  }

  process {
    walk ($json | ConvertFrom-Json)
  }

}

# Sample JSON input
$json = @'
  [ { "hi": 11 }, {
    "somekey1": "somevalue1",
    "somekey2": "somevalue2",
    "somekey3": 42,
    "somekey4": [
        "somevalue4.1",
        "somevalue4.2",
        4.42
      ],
    "somekey5": null
  } ]
'@


# Call with the sample string
$json | Get-JsonValue

The above yields the following:

11
somevalue1
somevalue2
42
somevalue4.1
somevalue4.2
4.42
# $null - not visible

Upvotes: 2

user13800089
user13800089

Reputation:

Thanks to Lee_Dailey - his filter produced the most results for me in grabbing all values from raw json to an array.

($InStuff -split [System.Environment]::NewLine).ForEach({$_.Split(':')[-1]}).Trim(' ",][')

Upvotes: 0

Related Questions