Skip to content

itskyedo/text-matcher

Repository files navigation

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


💡 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.

About

A simple text matching library.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •