text-matcher
v0.1.1
Published
A simple text matching library
Maintainers
Readme
text-matcher
A simple text matching library.
- 🚫 Zero dependencies
- 🪶 Simple and lightweight
- 😴 Matches are lazily evaluated
- 🧩 Support for custom non-regex rules
🚀 Getting Started
Installation
npm install text-matcher🗒️ Notes
- 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
💡 Usage
Match a single rule with matchRule
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"
}
]
*/Match multiple rules with matchAllRules
[!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"
}
}
]
}
]
*/Lazy matching
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().
Custom rules
[!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'
},
]
*/📃 License
MIT License. See LICENSE for details.
