Forgiving regex to extract key-value pairs from plain text files

Recording data manually (typing them with your fingers) in plain text files is still a viable option, even though not that common.

If what you are recording consists of multiple data values, you need some kind of key-value format. A simple format like this does the job:

First key:
Lorem ipsum dolor
 
Second key:
Nunc volutpat cursus

The rules can be summarized like this:

  • the key ends with a colon :
  • the value is on the next line
  • key-value pairs are delimited by empty lines

Whatever format you choose, you have to leave room for human error, e.g., extra spaces are very common.

Or you might want to allow some flexibility, or you expect long strings of text that should be broken into multiple lines to increase readability.

Here's an entry with some exaggerated formatting issues:

Alpha:
Lorem ipsum
 
Beta gamma:
dolor sit amet
consectetur adipiscing
elit
 
delta: quam vehicula
 
Epsilon:-Zeta:
Curabitur interdum massa
 
Eta:
Maecenas ac felis
 
Theta:
 
 
 
Iota:
Morbi at lobortis

In the end, if you are looking to extract a list of keys and values, you need a regex rule that goes beyond the basics:

[
[
"Alpha",
"Beta gamma",
"delta",
"Epsilon:-Zeta",
"Eta",
"Theta",
"Iota"
],
[
"Lorem ipsum",
"dolor sit amet\nconsectetur adipiscing\nelit",
"quam vehicula",
"Curabitur interdum massa",
"Maecenas ac felis",
"",
"Morbi at lobortis"
]
]

The regex that allows this amount of forgiveness looks like this:

[ ]*(.+):[ ]*\n?((?:.+\n?[^\s])*)

Use this pattern with the preg_match_all function, and you have a solid start to do something with the data.

To deconstruct the pattern, head over to RegEx101 where you will see the captured groups highlighted and the tokens annotated.