Rory :
I have a filter param in my REST API that can look like this:
owner='bob' // owner is bob
owner!'bob' // owner is not bob
owner.town='bel*' // owner's town starts with bel
owner.town='*bel*' // owner's town contains bel
owner.car='{ some json blob here}' // owner's car equals some json blob
owner.car~ // owner has a property named car
So I want to capture:
- A required String key
- The can contain letters, numbers, underscores, dots, hyphens or colons
- A required operator: +|!|~
- An optional value, that can begin and/or end with an optional asterisk
- If the optional value is present, it must be surrounded by single quotes
I have started with the following, buts it's not returning what I'd expect:
String filter = "owner='bob'";
Pattern.compile("(\\w+?)(=|!|~)(*?)(\\w+?)(*?)");
final Matcher matcher = pattern.matcher(filter);
// Results
matcher.group(1) // "owner"
matcher.group(2) // "="
matcher.group(3) // "\"
matcher.group(4) // ""
matcher.group(5) // "bob"
matcher.group(6) // ""
matcher.group(7) // "\"
Problems I'm having:
- I don't think
(*?)
is correctly capturing zero or one asterisks - Passing "owner~" results in a failure when invoking
matcher.group(anything)
I'm pretty sure there are other problems with the regex I havn't found yet...
Aaron :
I would use the following regex :
^([\w.:-]+)([=!~])('.*')?$
It is composed of three consecutive groups defined as follows :
- a first group matches the key, which is a non-empty sequence of letters, numbers, underscores, dots, hyphens or colons.
- a second group matches the operator, which is one of "=", "!" or "~"
- a third optional group matches the rest, which would be the property value when the operator isn't "~"
You can try it here.
Note that if the mention that the value can start or end with a *
is supposed to imply that it can't contain *
in other places you will want to change the third group into ('\*?[^*]*\*?')
.