Skip to content

Intermediate · Errors, modules and the standard library · topic 26 of 50 · 25 min

JSON and regular expressions

Explanation

JSON is the text format apps and websites use to send data. The json module turns Python dicts and lists into JSON text with dumps, and back again with loads. Regular expressions are small search patterns, like "ten digits starting with 6 to 9" for an Indian mobile number, and the re module uses them to search, find and replace text.

JSON: data as text

JSON (JavaScript Object Notation) is a way to write data as plain text. It looks almost like Python dicts and lists. When a weather app or a payment app talks to its server, the data usually travels as JSON.

python
import json
order = {"id": 101, "item": "Masala Dosa", "paid": True, "note": None}
text = json.dumps(order)
print(text)
print(type(text))
back = json.loads(text)
print(back["item"])
dumps: Python to JSON text. loads: JSON text to Python. Look at true and null.
Think of it like this: JSON is like a courier parcel. dumps packs your Python data into a flat box of text that any courier (any language: JavaScript, Java, Go) can carry. loads unpacks the box at the other end into Python data again.
PythonJSON
dictobject { }
list, tuplearray [ ]
strstring (always double quotes)
int, floatnumber
True / Falsetrue / false
Nonenull
python
import json
student = {"name": "Asha", "marks": [82, 91], "scholarship": False}
print(json.dumps(student, indent=2))
print(json.dumps({"b": 1, "a": 2}, sort_keys=True))
indent makes it readable; sort_keys puts keys in A to Z order.
Careful: JSON is stricter than Python. Strings and keys need double quotes, keys are always strings, and a tuple comes back as a list. json.loads("{'name': 'Asha'}") fails with json.JSONDecodeError, which is a kind of ValueError, so you can catch it.

Regular expressions

A regular expression (regex) is a short pattern that describes text, such as "one or more digits". Write patterns as raw strings, r"...", so Python leaves every backslash for the re module to read.

PatternMatches
\done digit, 0 to 9
\wone letter, digit or underscore
.any one character
[6-9]one character from 6 to 9
+one or more of the thing before it
*zero or more of the thing before it
?zero or one: the thing before it is optional
{6}exactly 6 of the thing before it
\ba word boundary: the edge of a word or number
python
import re
text = "Call Ravi on 9876543210 or the office on 080-22334455."
m = re.search(r"[6-9]\d{9}", text)
print(m.group())
print(re.findall(r"\d+", text))
print(re.sub(r"\d", "X", "PIN 560001"))
search finds the first match, findall finds all, sub replaces.

re.search looks for the pattern anywhere and gives a match object (or None). re.findall returns a list of every match. re.sub replaces each match. re.fullmatch checks that the whole text fits the pattern, which is what you want for checking a form field.

python
import re
def valid_mobile(s):
    return re.fullmatch(r"[6-9]\d{9}", s) is not None

def valid_pin(s):
    return re.fullmatch(r"[1-9]\d{5}", s) is not None

print(valid_mobile("9876543210"), valid_mobile("1234567890"))
print(valid_pin("560001"), valid_pin("056001"))
Indian mobiles: 10 digits starting 6 to 9. PIN codes: 6 digits, not starting with 0.
Tip: Build patterns slowly and test them on a few good and bad examples. A pattern that is too loose accepts junk; one that is too strict rejects real numbers written with a +91 or spaces, so clean the input first.

Watch the lesson

JSON and regular expressions · 1/6

json · re

Two everyday tools for working with text: JSON for sending data, and regular expressions for finding patterns.

Prefer a video by a teacher? Find free videos on “python json and regular expressions re module tutorial” on YouTube ↗

In real life: Cleaning a contact list for an SMS reminder

A tuition centre has a messy text file of parent contacts. Kiran pulls out every valid Indian mobile number with one regex, then saves the result as JSON so the SMS app can read it.

python
import re, json
notes = """Ravi papa 98765 43210, Asha mummy 7012345678
office 080-22334455, old number 5123456789"""
clean = notes.replace(" ", "")
# (?<!\d) and (?!\d) mean: no digit just before or just after
mobiles = re.findall(r"(?<!\d)[6-9]\d{9}(?!\d)", clean)
print(json.dumps({"count": len(mobiles), "numbers": mobiles}, indent=2))
Spaces removed first, then only real mobile numbers are kept.

Practice (0/3 done)

Task 1 · Code · Python

Write order_total(json_text). The text is JSON like {"items": [{"name": "Idli", "qty": 2, "price": 40}, ...]}. Return the total bill: the sum of qty × price for every item.

Task 2 · Code · Python

Write find_mobiles(text) that returns a list of every Indian mobile number in the text: exactly 10 digits, starting with 6, 7, 8 or 9, and not part of a longer number. Use re.findall with word boundaries \b.

Task 3 · Code · Python

Write valid_pin(pin) that returns True when pin is a valid Indian PIN code: exactly 6 digits, and the first digit is not 0. Use re.fullmatch.

Quick quiz

Question 1

1.What does json.dumps(True) return?

Question 2

2.Python None becomes what in JSON?

Question 3

3.What does the pattern r"\d+" match?

Question 4

4.What does re.findall return?

Question 5

5.Why write regex patterns as raw strings like r"..."?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: collections and itertools