Skip to content

Commit

Permalink
Enhancement: Add support for question mark (?) wildcards
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMa committed Jan 26, 2023
1 parent d2e8141 commit 3b5b3fd
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 9 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
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 3b5b3fd

Please sign in to comment.