npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

outmatch

v1.0.0

Published

An extremely fast and lightweight glob-matching library with advanced features

Downloads

45,830

Readme

Outmatch takes one or more glob patterns, compiles them into a RegExp and returns a function for matching strings with it.

Glob patterns are strings that contain wildcards such as *, ?, [abc] and others. When such a pattern is compared with another string, these wildcards can replace one or more symbols. For example, src/* would match both src/foo and src/bar.

While globs are usually used to search file paths separated by slashes, with outmatch it is possible to match arbitrary strings, whether separated or not.

Quickstart

npm install outmatch
import outmatch from 'outmatch'

const isMatch = outmatch('src/**/*.{js,ts}')

isMatch('src/components/header/index.js') //=> true
isMatch('src/README.md') //=> false

isMatch.pattern //=> 'src/**/*.{js,ts}'
isMatch.options //=> { separator: true }
isMatch.regexp //=> /^(?:src[/\\]+? ... \.ts[/\\]*?)$/

More details are available in the Installation, Usage, Syntax and API sections.

Features

For comparison with the alternatives, see the corresponding section.

Installation

The package is distributed via the npm package registry. It can be installed using one of the compatible package managers or included directly from a CDN.

npm

npm install outmatch

Yarn

yarn add outmatch

pnpm

pnpm install outmatch

CDN

When included from a CDN, outmatch is available as the global function outmatch.

Usage

Outmatch comes built in ESM, CommonJS and UMD formats and includes TypeScript typings. The examples use ESM imports, which can be replaced with the following line for CommonJS: const outmatch = require('outmatch').

The default export is a function of two arguments, first of which can be either a single glob string or an array of such patterns. The second argument is optional and can be either an options object or a separator (which will be the value of the separator option). Outmatch compiles them into a regular expression and returns a function (usually called isMatch in the examples) that tests strings against the pattern. The pattern, options and the compiled RegExp object are available as properties on the returned function:

import outmatch from 'outmatch'

const isMatch = outmatch('src/[bc]ar', { '{}': false })

isMatch('src/bar') //=> true
isMatch('src/car') //=> true
isMatch('src/tar') //=> false

isMatch.pattern //=> 'src/[bc]ar'
isMatch.options //=> { '{}': false }
isMatch.regexp //=> /^src[/\\]+?(?!\.)(?![/\\])[bc]ar[/\\]*?$/

The returned function can be invoked immediately if there is no need to match a pattern more than once:

outmatch('src/**/*.js')('src/components/body/index.js') //=> true

Compiling a pattern is much slower than comparing a string to it, so it is recommended to always reuse the returned function when possible.

File Paths and Separators

Globs are most often used to search file paths, which are, essentially, strings split into segments by slashes. While other libraries are usually restricted to this use-case, outmatch is able to work with arbitrary strings by accepting a custom separator via the second argument:

const matchDomain = outmatch('*.example.com', { separator: '.' })
matchDomain('subdomain.example.com') //=> true

const matchLike = outmatch('wh?t like**like mean', 'like') // shorthand for { separator: 'like' }
matchLike('what like do like you like mean') //=> true

The only limitation is that backslashes \ cannot be used as separators in patterns because outmatch uses them for character escaping. However, when separator is undefined or true, / in patterns will match both / and \, so a single pattern with forward slashes can match both Unix and Windows paths:

const isMatchA = outmatch('foo\\bar') // throws an error

const isMatchB = outmatch('foo/bar') // same as passing `true` as the separator

isMatchB('foo/bar') //=> true
isMatchB('foo\\bar') //=> true

const isMatchC = outmatch('foo/bar', '/')

isMatchC('foo/bar') //=> true
isMatchC('foo\\bar') //=> false

A thing to note is that most matching features work with a segment rather than a whole pattern. For example, foo/b* will match foo/bar but not foo/b/ar. The two exceptions to this are brace expansion and pattern negation, both of which work with whole patterns:

outmatch('src/{foo/bar,baz}')('src/foo/bar') //=> true (brace expansion)
outmatch('src/@(foo/bar|baz)')('src/foo/bar') //=> false (extglob)

Any string that contains a segment starting with a dot (a dotfile) is excluded unless the dot is specified explicitly in the pattern. This behavior can be disabled by setting excludeDot to false, in which case leading dots are treated like any other symbol:

outmatch('project/*')('project/.git') //=> false
outmatch('project/.*')('project/.git') //=> true (dot is specified explicitly)
outmatch('project/*', { excludeDot: false })('project/.git') //=> true

Segmentation can be turned off completely by passing false as the separator, which makes outmatch treat whole patterns as a single segment. Slashes become regular symbols, ** works identically to * and leading dots get excluded only when they are the very first character of a pattern:

const isMatch = outmatch('foo?ba*', false)
isMatch('foo/bar/.qux') //=> true

A single separator in a pattern will match any number of separators in a sample string:

outmatch('foo/bar/baz')('foo/bar///baz') //=> true

When a pattern has an explicit separator at its end, samples also require one or more trailing separators:

const isMatch = outmatch('foo/bar/')

isMatch('foo/bar') //=> false
isMatch('foo/bar/') //=> true
isMatch('foo/bar///') //=> true

However, if there is no trailing separator in a pattern, strings will match even if they have separators at the end:

const isMatch = outmatch('foo/bar')

isMatch('foo/bar') //=> true
isMatch('foo/bar/') //=> true
isMatch('foo/bar///') //=> true

Multiple Patterns

Outmatch can take an array of glob patterns as the first argument instead of a single pattern. In that case a string will be considered a match if it matches any of the given patterns:

const isMatch = outmatch(['src/*', 'tests/*'])

isMatch('src/utils.js') //=> true
isMatch('tests/utils.js') //=> true

If a negated pattern is given among positive patterns, it will work as an ignore filter for strings that match the positive patterns:

const isMatch = outmatch(['src/*', '!src/foo', '!src/bar'])

isMatch('src/foo') //=> false
isMatch('src/bar') //=> false
isMatch('src/baz') //=> true

Matching Arrays of Strings

The returned function can work with arrays of strings when used as the predicate of the native array methods:

const isMatch = outmatch(['src/**/*.js', '!**/body.js'])
const paths = ['readme.md', 'src/index.js', 'src/components/body.js']

paths.map(isMatch) //=> [ false, true, false ]
paths.filter(isMatch) //=> [ 'src/index.js' ]
paths.some(isMatch) //=> true
paths.every(isMatch) //=> false
paths.find(isMatch) //=> 'src/index.js'
paths.findIndex(isMatch) //=> 1

Syntax

API

outmatch(patterns, options?): isMatchoutmatch(patterns, separator?): isMatch

Takes a single pattern string or an array of patterns and compiles them into a regular expression. Returns an isMatch function that takes a sample string as its only argument and returns true if the string matches the pattern(s).

isMatch(sample): boolean

Tests if a sample string matches the patterns that were used to compile the regular expression and create this function.

isMatch.regexp

The compiled regular expression.

isMatch.pattern

The original pattern or array of patterns that was used to compile the regular expression and create the isMatch function.

isMatch.options

The options object that was used to compile the regular expression and create the isMatch function.

Options

| Option | Type | Default Value | Description | | ------------ | --------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | separator | string | boolean | true | Separator to be used to split patterns and samples into segments:true/ in patterns match both / and \ in samplesfalse — don't splitany string — custom separator | | flags | string | undefined | Flags to pass to the RegExp. For example, setting this option to 'i' will make the matching case-insensitive | | excludeDot | boolean | true | Toggles whether to exclude strings that contain segments starting with a dot | | ! | boolean | true | Toggles pattern negation | | ? | boolean | true | Toggles single-char wildcards | | * | boolean | true | Toggles multi-char wildcards | | ** | boolean | true | Toggles globstars | | [] | boolean | true | Toggles character classes | | () | boolean | true | Toggles extglobs | | {} | boolean | true | Toggles brace expansion |

Comparison

Pattern: src/test/**/*.?s
Sample: src/test/foo/bar.js

Compilation
  outmatch     650,098 ops/sec
  picomatch    136,927 ops/sec

Matching
  outmatch     34,524,204 ops/sec
  picomatch    10,223,739 ops/sec