How to parse JSON file and extract specific fields in Perl?
Question
How to parse JSON file and extract specific fields in Perl?
Parsing JSON and Extracting Fields in Perl
Parsing JSON in Perl is straightforward and commonly done using core or well-established CPAN modules like JSON or JSON::PP>. These modules convert JSON strings into Perl data structures (hashes and arrays), enabling easy data extraction.
Below is a comprehensive guide on how to parse JSON and extract specific fields, along with a runnable Perl example you can execute directly. This example illustrates key Perl concepts like sigils, context, and typical gotchas.
Step-by-step approach
- Read JSON content: Often from a file or string.
- Decode JSON: Convert JSON text to Perl data structures (using
decode_json). - Access fields: Use Perl hashes or arrays to extract specific values.
- Handle errors: Use eval or check for decoding failures.
Perl Specifics
$sigil indicates scalar (string, number, ref).@sigil for arrays.%sigil for hashes.- JSON decoding returns references usually (e.g. hashref).
- Context matters: accessing
$data->{key}vs@{ $data->{array} }. - Perl's TMTOWTDI ("There's more than one way to do it") applies; several JSON modules exist, but
JSON::PPis core and reliable.
Example: Parse JSON string and extract fields
This example demonstrates how to parse a JSON string representing a user list, then extracts and prints the name and email of each user.
use strict;
use warnings;
use JSON::PP; # Core from Perl 5.14+, pure Perl fallback
# Sample JSON text (could be read from a file)
my $json_text = q|{
"users": [
{ "name": "Alice", "email": "alice@example.com", "age": 30 },
{ "name": "Bob", "email": "bob@example.com", "age": 25 },
{ "name": "Carol", "email": "carol@example.com", "age": 27 }
]
}|;
# Decode JSON string into Perl data structure (hashref)
my $data = eval { decode_json($json_text) };
if ($@) {
die "Failed to decode JSON: $@";
}
# Access the arrayref of users
my $users = $data->{users};
# Print extracted fields
foreach my $user (@$users) {
# $user is a hashref for each user
my $name = $user->{name} // 'Unknown';
my $email = $user->{email} // 'No email';
print "Name: $name, Email: $email\n";
}
Explanation
We use decode_json from JSON::PP to convert the JSON string into a Perl hash reference. The key users holds an array reference, so accessing $data->{users} provides that array reference. Iterating through @$users retrieves each user's hashref, letting us directly access {name} and {email}.
The use of the defined-or operator // ensures we have default values when keys are missing.
Common Pitfalls
- Failing to decode JSON and not checking for errors (use
evalor error checking). - Misunderstanding references and forgetting to dereference arrays/hashes.
- Assuming JSON keys are always present (handle undefined values gracefully).
- Confusing scalar vs list context when extracting data.
- Using non-core JSON modules without installation, which can cause portability issues.
Notes on Version and Modules
JSON::PPis a pure-Perl module bundled with Perl 5.14 and newer, making it great for portability.- Alternatively,
JSONorJSON::XScan be faster but may require CPAN installation. - The example works on Perl 5.14+ without external dependencies.
This example should serve as a base for extracting fields from JSON. For files, simply replace the hardcoded string and read the JSON content from the file like this:
open my $fh, "<", "file.json" or die $!;
my $json_text = do { local $/; <$fh> };
close $fh;
With this setup, you can extend parsing to more complex nested data and various field extractions with confidence.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 24ms
Name: Alice, Email: alice@example.com
Name: Bob, Email: bob@example.com
Name: Carol, Email: carol@example.com
(empty)