-1

If I am given a sample string like the one given below and I want to extract ids and code values

demo = '{"orders":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9}],"errors":[{"code":3,"message":"[PHP Warning #2] count(): Parameter must be an array or an object that implements Countable (153)"}]}'

using regex

r'"id":([0-9]+)' gets me the ids i.e 1,2,3,4 etc but I am having trouble getting the value inside the key code in one regex expression.

I searched for AND operators and stumbled upon

Regular Expressions: Is there an AND operator?

but this approach doesn't help me.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Shorya Sharma
  • 457
  • 3
  • 10
  • The question you linked to has 12 answers. Can you explain more clearly why none of them would be the answer to your question? – IMSoP Aug 30 '20 at 16:50
  • WHy would you do this with a regexp? Use a JSON parser and extract what you want from the resulting object. – Barmar Aug 30 '20 at 16:53
  • @IMSoP The answers to the linked question does pattern matching to a string like "Start with a good word and end with a kind deed" and "Start with a kind word and end with a good deed". In my case I want to extract values of two different keys in a single regex expression . – Shorya Sharma Aug 30 '20 at 16:55
  • @Barmar I know that JSON parser is a better way to go was just curious as to how can this be applied using a Regex Format – Shorya Sharma Aug 30 '20 at 16:56
  • It's the same as the way you get the id: `r'"code":([0-9]+)'` – Barmar Aug 30 '20 at 16:58
  • What does the AND operator have to do with this? – Barmar Aug 30 '20 at 16:58
  • @Barmar I want to get the values inside the ids AND code together. – Shorya Sharma Aug 30 '20 at 17:01
  • Be aware that's an OR, not an AND – martinspielmann Aug 30 '20 at 17:15
  • @martinspielmann This OR operator gives me the keys and the values as a set i.e ('id' : '1') but what I really want is a single regex expression to get the values i.e 1,2,3,4,5, etc – Shorya Sharma Aug 30 '20 at 17:23

2 Answers2

3

Use the | operator to match alternatives:

result = re.findall(r'"(id|code)":([0-9]+)', demo)
print(result)
# prints
[('id', '1'), ('id', '2'), ('id', '3'), ('id', '4'), ('id', '5'), ('id', '6'), ('id', '7'), ('id', '8'), ('id', '9'), ('code', '3')]
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Use ast.literal_eval() instead as your "string" is indeed structured information:

from ast import literal_eval

demo = '{"orders":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9}],"errors":[{"code":3,"message":"[PHP Warning #2] count(): Parameter must be an array or an object that implements Countable (153)"}]}'

demo = literal_eval(demo)

result = {key: [dct.get(key) for dct in demo[needle]]
          for key, needle in [('id', 'orders'), ('code', 'errors')]}
print(result)

This yields

{'code': [3], 'id': [1, 2, 3, 4, 5, 6, 7, 8, 9]}
Jan
  • 42,290
  • 8
  • 54
  • 79