efficient regex for key/value matches

Viewed 77

Let's say I have a string that represents a list of unique key/value pairs like so:

a:1;b:2;c:3;d:4

Checking whether the string contains a specific key/value pair is straight forward. But let's say I want to take advantage of the fact that the keys are unique. Is there a way to optimize the regex so that if it finds a key with a value different than the one I want, it immediately fails rather than continue scanning to the end of the string?

So, in the example above, if I want to see if b:3 is in the string, I'd want the match to fail as soon as it finds b:2. (note: an inverse search for something like b:[^3] isn't going to work for cases where they key b is missing)

3 Answers

I think the fastest will be to use a two step approch. Idon't know what programming language, you're using (so this is pseudicode), but use this regex:

b:(\d)

This will find the first 'b:' in the string and save the value as Group 1. Now check if the value in Group 1 is the one, you want.

For instance in JavaScript you could do:

var text = 'a:1;b:2;c:3;d:4';
var match = text.match(/b:(\d)/);
if (match[1] === '3')
{
    return true;
}
else
{
    return false;
}

This will be a very fast approach.

DEMO

^[^b]*b:3

Explanation:
Asserting that the match starts at the begging of the line with ^ guarantees that a line will contain exactly one match. using [^b]* expands the match to the first occurrence of 'b' and terminates the expansion, as it's not allowed to move past there. finally, the evaluation of b:3 occurs which either validate or invalidate the match, with no chance of re-evaluation or backtracking as the only quantifier is terminated

Something like this could work:

import re 

for dic in [{"a":1},{"b":2}]:   
    for  k,v in dic.items():
        regex = r".+?;%s:[^%d]" %(k,v)
        if re.match(regex, test): break
Related