-2

In the following JSON, how can I use a regular expression to match the parent key named "Item of Equipment", whose value is changing and unpredictable?

"type": "title" Is unique to this node, as is presence of "title:".

AKA: "How can I match a parent value by using a child?

An alternative to find "Item of Equipment" is to look for it in the property "name", where it is duplicated, as a sibling of "type": "title". It's the case that "type": "title" always uniquely has a sibling of "name"

    ..
    "id": "Xkt@",
    "name": "My Email",
    "type": "email"
  },
  "Item of Equipment": {
    "id": "title",
    "title": {},
    "name": "Item of Equipment",
    "type": "title"
  },
  "My Date": {
    "id": "nYcK",
    "name": "My Date",
    "type": "date",
    ..

I won't use a JSON parser, I won't have access. I am running this through the "Match" action of iOS Shortcuts.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Robert Andrews
  • 1,209
  • 4
  • 23
  • 47

1 Answers1

0

Notes

  1. Based on JSON validation via RegEx.
  2. Addition of "Atomic Groups" to avoid backtracking.
  3. Assumption that the iOS "Match" uses regular expressions (ICU) similar to Perl.
  4. If a single line regular expression is required, that is left for an exercise for the reader.
  5. Note performance / usability with large JSON input may cause regular expression engine to have issues ("your mileage may vary").

RegEx

(?(DEFINE)
     (?<number>   (?>-? (?= [1-9]|0(?!\d) ) \d+ (\.\d+)? ([eE] [+-]? \d+)?) )
     (?<boolean>   (?> true | false | null ))
     (?<unquoted>  (?>  ([^"\\]* | \\ ["\\bfnrt\/] | \\ u [0-9a-f]{4} )* ))
     (?<string>    (?>" (?&unquoted) " ))
     (?<array>     (?> \[  (?:  (?&json)  (?: , (?&json)  )*  )?  \s* \] ))
     (?<pair>      (?> \s* (?&string) \s* : (?&json)  ))
     (?<object>    (?>\{  (?:  (?&pair)  (?: , (?&pair)  )*  )?  \s* \} ))
     (?<json>   (?>\s* (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) \s* ))
  )
(?<=")           # Lookbehind for quote before parent key string
(?&unquoted)     # parent key string 
(?=              # Lookahead for object properties including unique property marker
"\s*:\s*{\s*
(?:  (?&pair)  (?: , (?&pair)  )*  )?    # any number of property key value pairs, optional.
(?:(?:\s* , )?\s* "type"\s*:\s*"title")  # unique property marker, optionally perfixed with comma.
(?: \s*, (?&pair)  )*                    # any number of property key value pairs, optional.
\s*}
)

Proof

https://regex101.com/r/kN74Th/1

Dean Taylor
  • 40,514
  • 3
  • 31
  • 50