Extract string from list

Hi I have a unique case where I need to extract a string under a split from a simple list (no keys just values)

“string1a|string1b,string2a|string2b”
“string3a|string3b,string4a|string4b”

I do a foreach on the above
Then split on “,” and I now need to extract from the split (regexmacth) value starting with string1a (for example)
Then a further split on this extracted string using the “|” delimter

Any idea ?

I am trying all methods of madness but none seem to work

here is the latest one i am trying

for_each = { for i, v in local.listmap : i => v }


somevar = split(“,”,each.value)[index([for v in split(“,”,each.value) : v], regex(“config.*”,v))]

I tried this also

somevarstring = { for k, item in split(“,”,each.value) : k => item if can(regex(“config”, item))}

I am just testing on the split for “,” not got to the “|” split yet…

Hi @mkocaks,

For a problem like this I’d typically start by trying to project the input into a more reasonably-shaped data structure. Using a better-suited data structure will then make the rest of the problem easier to describe.

You didn’t share any code so I’m going to assume the following input variable representing the input data you shared:

variable "input" {
  type = list(string)

  default = [
    "string1a|string1b,string2a|string2b",
    "string3a|string3b,string4a|string4b",
  ]
}

To implement the logic you described I expect I’d prefer to have a data structure shaped like this:

[
  ["string1a", "string1b"],
  ["string2a", "string2b"],
  ["string3a", "string3b"],
  ["string4a", "string4b"],
]

Here’s one way to achieve that structure:

locals {
  transformed = tolist(concat([
    for s in var.input : [
      for seq in split(",", s) :
      split("|", seq)
    ]
  ]...))
}

You could then use local.transformed for your subsequent filtering and transformation steps. For example, you could apply your regex pattern to the first element of each of the nested lists to select only the pairs whose first element matches the pattern.

Thank you for the fast feedback greatly appreciated, for better context the input derives from data external (runs a PS Script) - the json output limitation of data external I ended up with this source data.
Each value in the list will be fed into a template file i.e. each string in the list will be template file 0,1,2 and so on…
Then within each value in the list contains the values I need to feed in as variables delimited by first “,” then “|” (the template file creates a dashboard in azure - json file - and will contain panels for various metrics contained in the string value delimited by “,” and “|”.
I will look at transformed way above and feedback :slight_smile: thank you once again

I am still exploring this and making some changes but running into an issue where I cannot nest any further in the transform…
I now have this as my source data

[
“A1 : B1 | C1 , X1 : Y1 | Z1”,
“A2 : B2 | C2 , X2 : Y2 | Z2”,
etc…
]

And I need to transform this into

[
[
A1 = {
“B1”,
“C1”
},
X1 = {
“Y1”,
“Z1”
}
],
[
A2 = {
“B2”,
“C2”
},
X2 = {
“Y2”,
“Z2”
}

]

]

I cannot seem to get the right side of : as child objects under the left side of : ? They end up on the same level ?

I been toying with transform (I know this is nested arrays but happens also the same for objects when using k, v… wrapped in { }

transformed = tolist(concat([

    for s in local.listmap : [
      
      for seq in split(",", s) : [

        for seq1 in split(":",seq) : [
          
          for seq2 in split("|", seq1) :
            seq2
        ]
    ]
]

]))

I am still relatively new to HCL however there are some corner cases where I find HCL very limited and spend a huge amount of time trying to workaround limitations which should not exist (i.e. if data external could handle valid but complex json outputs I would not of spent 3 days so far trying to fix / workaround the limitations)

HCL is a configuration language - or, the framework from which applications build a configuration language by adding application-specific behaviour.

When you say HCL, I think you more properly mean Terraform.

The fact that terraform-provider-external’s data source requires a strict map of strings is indeed a limitation, that comes from Terraform’s approach of applying schema to data source / resource inputs and outputs.

If this is a problem for you, I strongly suggest returning a complex JSON object as a single string value within the map from the external script, and then applying jsondecode() to it within a Terraform expression.

This would be a significantly easier workaround than the complex structures you’re currently developing within this topic.

Worked it out with my work colleague in the end :slight_smile:

transformed = tolist(concat([
        for s in local.listmap : merge([
          for seq in split(",", s) : { 
            "${split(":",seq)[0]}"= {
              lunid = split("|",split(":",seq)[1])[0],
              vmss_id = split("|",split(":",seq)[1])[1]
             }
          }
        ]...)
    ]
  ))