text-processing intermediate

How to convert CSV to JSON in Perl?

Question

How to convert CSV to JSON in Perl?

How to Convert CSV to JSON in Perl

Converting CSV (Comma-Separated Values) data to JSON (JavaScript Object Notation) is a common task in text processing and data interchange. Perl excels at text manipulation, and with its core modules and rich ecosystem, you can easily handle CSV-to-JSON conversion.

This answer demonstrates a straightforward approach using only core Perl modules — no external CPAN dependencies — which makes your script portable and simple to run. We will:

  • Parse CSV data using Perl's builtin Text::ParseWords module to handle quoted fields properly
  • Build Perl data structures representing the rows as hashes keyed by CSV headers
  • Encode the resulting structure to JSON using Perl’s core JSON::PP module (available since Perl 5.14)

Key Perl Concepts Illustrated

  • @array (array sigil @) is used to handle list context for CSV fields
  • %hash (hash sigil %) creates row-based key/value pairs from CSV headers and fields
  • TMTOWTDI ("There's More Than One Way To Do It") is reflected here as you could use a dedicated CSV module like Text::CSV, but Text::ParseWords suffices for simple parsing
  • Scalar vs. list context: we parse line into an array, then map into a hash

Common Gotchas

  • Improper CSV parsing can fail on quoted commas or embedded newlines. For complex CSV, prefer Text::CSV.
  • Header count mismatch with data fields can cause errors; simple scripts assume consistent CSV files.
  • JSON::PP is a pure-Perl JSON encoder included in Perl core >= 5.14, but on older versions you might need to install JSON::XS or JSON.

Runnable Perl Example

use strict;
use warnings;
use feature 'say';

use Text::ParseWords qw(parse_line);
use JSON::PP;

my $csv_data = <<'END_CSV';
name,age,city
Alice,30,"New York"
Bob,25,Los Angeles
Charlie,35,Chicago
END_CSV

# Split the CSV data into lines
my @lines = split /\n/, $csv_data;

# Parse header row to get field names
my $header_line = shift @lines;
my @headers = parse_line(',', 0, $header_line);

my @rows;
for my $line (@lines) {
    next if $line =~ /^\s*$/;    # skip empty lines
    my @fields = parse_line(',', 0, $line);
    # Pair up header => field into a hash for each row
    my %row;
    @row{@headers} = @fields;
    push @rows, \%row;
}

# Convert the Perl data structure (arrayref of hashrefs) to JSON
my $json = JSON::PP->new->utf8->pretty->encode(\@rows);

say $json;

Output Explanation

The script parses a multiline CSV string with headers `name,age,city`. For each record, it constructs a hash mapping CSV columns to values, stores these hashes in an array, then encodes the array of hashes as nicely formatted JSON.

Running this will print:

[
   {
      "name" : "Alice",
      "age" : "30",
      "city" : "New York"
   },
   {
      "name" : "Bob",
      "age" : "25",
      "city" : "Los Angeles"
   },
   {
      "name" : "Charlie",
      "age" : "35",
      "city" : "Chicago"
   }
]

Summary

Perl makes CSV to JSON conversion easy with core modules: Text::ParseWords safely splits CSV fields even with quotes, while JSON::PP (included since Perl 5.14) encodes Perl data structures as JSON. For very complex CSV, Text::CSV CPAN module is recommended, but this lightweight script works great for common cases.

Remember the Perl sigils and context rules: arrays hold rows of fields, hashes map headers to values, and everything comes together elegantly to convert tabular CSV data into flexible JSON format.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 28ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
[
   {
      "city" : "New York",
      "age" : "30",
      "name" : "Alice"
   },
   {
      "name" : "Bob",
      "city" : "Los Angeles",
      "age" : "25"
   },
   {
      "age" : "35",
      "city" : "Chicago",
      "name" : "Charlie"
   }
]

STDERR
(empty)

Was this helpful?

Related Questions