A simple text matching library.
- 🚫 Zero dependencies
- 🪶 Simple and lightweight
- 😴 Matches are lazily evaluated
- 🧩 Support for custom non-regex rules
npm install text-matcher- All regex rules must have the global (
g) and multiline flags (m) in the expression - Rules can either a be Regular Expression or a Generator that yields a
Matchobject
import { matchRule } from 'text-matcher';
const matches = matchRule(/\n/gm, 'Line1\nLine2\nLine3');
console.log(Array.from(matches));
/*
Output: [
{
"start": 5,
"end": 5,
"value": "\n"
},
{
"start": 11,
"end": 11,
"value": "\n"
}
]
*/Note
Each rule parses the text independently, so it's best to optimize by using lazy matching and minimizing the number of rules.
The left property is a reference to the match with the smallest start value, selecting the lengthiest match if multiple matches share the same value. The right property follows the same logic, referencing the match with the largest end value.
import { matchAllRules } from 'text-matcher';
const matches = matchAllRules('/* // Comment */ Text', {
slashStarComments: /(\/\*[\s\S]*?\*\/)(\n?)/gm,
// It's recommended to name your capture groups `(?<name>)` for easy extraction
doubleSlashComments: /(\/\/)(?<message>.*)(\n?)/gm,
});
console.log(Array.from(matches));
/*
Output: [
{
"start": 0,
"end": 20,
"left": {
"rule": "slashStarComments",
"start": 0,
"end": 15,
"value": "/* // Comment *\/"
},
"right": {
"rule": "doubleSlashComments",
"start": 3,
"end": 20,
"value": "// Comment *\/ Text",
"groups": {
"message": " Comment *\/ Text"
}
},
"matches": [
{
"rule": "slashStarComments",
"start": 0,
"end": 15,
"value": "/* // Comment *\/"
},
{
"rule": "doubleSlashComments",
"start": 3,
"end": 20,
"value": "// Comment *\/ Text",
"groups": {
"message": " Comment *\/ Text"
}
}
]
}
]
*/import { matchRule } from 'text-matcher';
const matches = matchRule(/\n/gm, 'Line1\nLine2\nLine3');
const firstMatch = matches.next();
await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds
const secondMatch = matches.next();Alternatively, you can use a for-of or while loop to iterate over each match or store all matches as an array by using Array.from().
Note
Custom rules can yield matches with arbitrary values, so thorough testing is essential to ensure accurate results.
import { type Match, matchRule } from 'text-matcher';
function* customRule(text: string): Generator<Match, undefined> {
for (let i = 0; i < text.length; i++) {
yield {
start: i,
end: i,
value: text[i],
groups: undefined,
};
}
}
const matches = matchRule(customRule, 'abc');
console.log(Array.from(matches));
/*
Output: [
{
start: 0,
end: 0,
value: 'a'
},
{
start: 1,
end: 1,
value: 'b'
},
{
start: 2,
end: 2,
value: 'c'
},
]
*/MIT License. See LICENSE for details.