Skip to content

Commit

Permalink
feat: add support for question mark (?) wildcards (#25)
Browse files Browse the repository at this point in the history
Co-authored-by: Gajus Kuizinas <gajus@gajus.com>
  • Loading branch information
MartinMa and gajus authored Oct 3, 2023
1 parent be00757 commit efb877d
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 12 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ name:/foo/o

# search using wildcard
name:foo*bar
name:foo?bar

# boolean search
member:true
Expand Down Expand Up @@ -202,6 +203,12 @@ Search for `name` field values matching `f*o` wildcard pattern.
name:f*o
```

Search for `name` field values matching `f?o` wildcard pattern.

```rb
name:f?o
```

Search for phrase "foo bar" in the `name` field (case sensitive).

```rb
Expand Down Expand Up @@ -250,12 +257,24 @@ Search for any word that starts with "foo" in the `name` field.
name:foo*
```

Search for any word that starts with "foo" and ends with bar in the `name` field.
Search for any word that starts with "foo" and ends with "bar" in the `name` field.

```rb
name:foo*bar
```

Search for any word that starts with "foo" in the `name` field, followed by a single arbitrary character.

```rb
name:foo?
```

Search for any word that starts with "foo", followed by a single arbitrary character and immediately ends with "bar" in the `name` field.

```rb
name:foo?bar
```

### Boolean operators

Search for phrase "foo bar" in the `name` field AND the phrase "quick fox" in the `bio` field.
Expand Down
6 changes: 4 additions & 2 deletions src/convertWildcardToRegex.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const WILDCARD_RULE = /\*+/g;
const WILDCARD_RULE = /(\*+)|(\?)/g;

export const convertWildcardToRegex = (pattern: string): RegExp => {
return new RegExp(
pattern
.replace(WILDCARD_RULE, '(.+?)'),
.replace(WILDCARD_RULE, (_match, p1) => {
return p1 ? '(.+?)' : '(.)';
}),
);
};
4 changes: 2 additions & 2 deletions src/createStringTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export const createStringTest = (regexCache: RegExpCache, ast: LiqeQuery) => {

const value = String(expression.value);

if (value.includes('*') && expression.quoted === false) {
return createRegexTest(regexCache, String(convertWildcardToRegex(value)) + (expression.quoted ? 'u' : 'ui'));
if ((value.includes('*') || value.includes('?')) && expression.quoted === false) {
return createRegexTest(regexCache, String(convertWildcardToRegex(value)) + 'ui');
} else {
return createRegexTest(regexCache, '/(' + escapeRegexString(value) + ')/' + (expression.quoted ? 'u' : 'ui'));
}
Expand Down
2 changes: 1 addition & 1 deletion src/grammar.ne
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,4 @@ regex_flags ->
[gmiyusd]:+ {% d => d[0].join('') %}

unquoted_value ->
[a-zA-Z_*@#$] [a-zA-Z\.\-_*@#$]:* {% d => d[0] + d[1].join('') %}
[a-zA-Z_*?@#$] [a-zA-Z\.\-_*?@#$]:* {% d => d[0] + d[1].join('') %}
4 changes: 2 additions & 2 deletions src/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ const grammar: Grammar = {
{"name": "regex_flags$ebnf$1", "symbols": ["regex_flags$ebnf$1", /[gmiyusd]/], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "regex_flags", "symbols": ["regex_flags$ebnf$1"], "postprocess": d => d[0].join('')},
{"name": "unquoted_value$ebnf$1", "symbols": []},
{"name": "unquoted_value$ebnf$1", "symbols": ["unquoted_value$ebnf$1", /[a-zA-Z\.\-_*@#$]/], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "unquoted_value", "symbols": [/[a-zA-Z_*@#$]/, "unquoted_value$ebnf$1"], "postprocess": d => d[0] + d[1].join('')}
{"name": "unquoted_value$ebnf$1", "symbols": ["unquoted_value$ebnf$1", /[a-zA-Z\.\-_*?@#$]/], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "unquoted_value", "symbols": [/[a-zA-Z_*?@#$]/, "unquoted_value$ebnf$1"], "postprocess": d => d[0] + d[1].join('')}
],
ParserStart: "main",
};
Expand Down
12 changes: 10 additions & 2 deletions test/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
filter,
} from '../src/Liqe';

const randomInRange = (min, max) => {
const randomInRange = (min: number, max: number) => {
return Math.floor(
Math.random() * (Math.ceil(max) - Math.floor(min) + 1) + min,
);
Expand Down Expand Up @@ -71,14 +71,22 @@ void suite(
};
}),

add('filters list by the "name" field using wildcard check', () => {
add('filters list by the "name" field using star (*) wildcard check', () => {
const query = parse('name:Ga*');

return () => {
filter(query, persons);
};
}),

add('filters list by the "name" field using question mark (?) wildcard check', () => {
const query = parse('name:Gaju?');

return () => {
filter(query, persons);
};
}),

add('filters list by any field using loose inclusion check', () => {
const query = parse('Gajus');

Expand Down
4 changes: 4 additions & 0 deletions test/liqe/convertWildcardToRegex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ const testRule = test.macro((t, regex: RegExp) => {
});

test('*', testRule, /(.+?)/);
test('?', testRule, /(.)/);
test('foo*bar', testRule, /foo(.+?)bar/);
test('foo***bar', testRule, /foo(.+?)bar/);
test('foo*bar*', testRule, /foo(.+?)bar(.+?)/);
test('foo?bar', testRule, /foo(.)bar/);
test('foo???bar', testRule, /foo(.)(.)(.)bar/);
19 changes: 17 additions & 2 deletions test/liqe/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ test(
);

test(
'matches wildcard',
'matches star (*) wildcard',
testQuery,
'name:f*o',
{
Expand All @@ -118,7 +118,7 @@ test(
);

test(
'matches wildcard (lazy)',
'matches star (*) wildcard (lazy)',
testQuery,
'name:f*o',
{
Expand All @@ -132,6 +132,21 @@ test(
],
);

test(
'matches question mark (?) wildcard',
testQuery,
'name:f?o',
{
name: 'foo bar baz',
},
[
{
path: 'name',
query: /(foo)/,
},
],
);

test(
'matches regex',
testQuery,
Expand Down

0 comments on commit efb877d

Please sign in to comment.