efficient regex for key/value matches
up vote
2
down vote
favorite
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)
regex
add a comment |
up vote
2
down vote
favorite
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)
regex
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
Use a lookahead assertion^(?!.*b:[^3]).*b:3
– sln
Nov 7 at 17:31
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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)
regex
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)
regex
regex
asked Nov 7 at 17:11
Dmitry B.
6,1492847
6,1492847
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
Use a lookahead assertion^(?!.*b:[^3]).*b:3
– sln
Nov 7 at 17:31
add a comment |
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
Use a lookahead assertion^(?!.*b:[^3]).*b:3
– sln
Nov 7 at 17:31
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
Use a lookahead assertion
^(?!.*b:[^3]).*b:3– sln
Nov 7 at 17:31
Use a lookahead assertion
^(?!.*b:[^3]).*b:3– sln
Nov 7 at 17:31
add a comment |
3 Answers
3
active
oldest
votes
up vote
0
down vote
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.
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
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
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
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.
add a comment |
up vote
0
down vote
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.
add a comment |
up vote
0
down vote
up vote
0
down vote
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.
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.
answered Nov 7 at 18:02
Poul Bak
5,26831132
5,26831132
add a comment |
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
up vote
0
down vote
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
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
answered Nov 7 at 18:09
petruz
461311
461311
add a comment |
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
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
add a comment |
up vote
0
down vote
up vote
0
down vote
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
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
edited Nov 7 at 18:16
answered Nov 7 at 18:09
doom87er
38717
38717
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53194447%2fefficient-regex-for-key-value-matches%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This won't reduce complexity though, assuming position are random, the complexity are going to be the same.
– Rocky Li
Nov 7 at 17:15
Use a lookahead assertion
^(?!.*b:[^3]).*b:3– sln
Nov 7 at 17:31