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

regex-extract-loader

v1.0.2

Published

A webpack loader to extract values from files with regex

Downloads

41

Readme

regex-extract-loader

Build Status

A webpack loader that uses regex to extract values from source files and make them available in code, or transform source into another form.

The regex-extract-loader takes a file's content as input, runs it against a user-supplied regular expression, and returns match information as its output by default. The output can be transformed, either on a per-match basis or at the end of the entire operation, using the match and/or project functions.

Example usage

Extract the attribute data from path tags in an svg file.

some.source.svg (input)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3046.7 875.7">
  <title>webpack-logo</title>
  <path class="back" fill="#FFF" d="M387 0l387 218.9v437.9L387..."/>
  <path class="outer" fill="#8ED6FB" d="M704.9 641.7L399.8 814..."/>
  <path class="inner" fill="#1C78C0" d="M373 649.3L185.4 546...."/>
</svg>

webpack.config.js (config)

module.exports = {
  ...,
  module: {
    rules: [{
      test: /\.source.svg$/,
      use: {
        loader: 'regex-extract-loader',
        options: {
          regex: 'path.+\\bd="(.+?)"',  // can also be a RegExp object (required)
          flags: 'g'                    // ignored if a RegExp is used (optional)
          match: (match) => match,      // called for each match (optional)
          project: (result) => result   // called after processing (optional)
        }
      }
    }]
  }
}

some.module.js (output)

const pathData = require('./assets/some.source.svg')

  // Because the global flag was used, the result is an array of RegExp match objectss.
  [
    // First match
    [
      // 0: the entire match
      'path class="back" fill="#FFF" d="M387 0l387 218.9v437.9L387..."',
      // 1: the first (and only) capture group
      'M387 0l387 218.9v437.9L387...',
      // index: the index of the match in the input
      index: 101,
      // input: the entire input string
      input: '<svg xmlns="http://www.w3.org/2000/svg" viewBox=...>...</svg>'
    ],
    // Second match
    [
      'path class="outer" fill="#8ED6FB" d="M704.9 641.7L399.8 814..."',
      'M704.9 641.7L399.8 814...',
      index: 170,
      input: '<svg xmlns="http://www.w3.org/2000/svg" viewBox=...>...</svg>'
    ],
    // Third match
    [
      'path class="inner" fill="#1C78C0" d="M373 649.3L185.4 546...."',
      'M373 649.3L185.4 546....',
      index: 239,
      input: '<svg xmlns="http://www.w3.org/2000/svg" viewBox=...>...</svg>'
    ]
  ]

By default the entire match object is returned in the list, which includes the entire input. With the match and/or project options this can be pared down or transformed. See Using match and Using project below for details.

Typescript

Using import instead of require may cause issues when using Typescript to import text files. In this case, include a declarations.d.ts file in your project:

declarations.d.ts

declare module '*.svg' {
  const svg: any
  export default svg
}

declare module '*.txt' {
  const txt: any
  export default txt
}

Then you should be able to import the file:

import pathData from './source.svg'
import text from './somefile.txt'

Options object

options: {
  regex: 'path.+\\bd="(.+?)"',
  flags: 'g',
  match: (match) => match,
  project: (result) => result
}

regex (string|RegExp) (required) can be a string or RegExp object. For strings make sure escape characters use a double backslash, e.g., \\w+.

flags (string) (optional) used if regex is a string, otherwise ignored. If g (global) is specified either in the flags property or in the supplied regex, an array of RegExp match objects is returned. Otherwise a single RegExp match object is returned.

match (function) (optional) called for each match. Can be used to modify each match object. Must return a value if used.

project (function) (optional) called at the end of processing. Can be used to modify the final result. Must return a value if used.

Output: If the global flag g was used, the output will be a list of RegExp match objects. Otherwise it will be a single RegExp match object.

Using match

The match option can be used to modify the content of individual matches. A common use case is to return from the match object only items that would be needed in the final result. Since regex-extract-loader by default returns the RegExp match object, which includes the entire source string, it's much more efficient to only send along whatever is needed.

some.source.svg (input)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3046.7 875.7">
  <title>webpack-logo</title>
  <path class="back" fill="#FFF" d="M387 0l387 218.9v437.9L387..."/>
  <path class="outer" fill="#8ED6FB" d="M704.9 641.7L399.8 814..."/>
  <path class="inner" fill="#1C78C0" d="M373 649.3L185.4 546...."/>
</svg>

webpack.config.js (config)

module.exports = {
  ...,
  module: {
    rules: [{
      test: /\.source.svg$/,
      use: {
        loader: 'regex-extract-loader',
        options: {
          regex: 'path.+\\bd="(.+?)"',
          flags: 'g'
          // Return the first (and only) caputre group
          match: (match) => match[1]
        }
      }
    }]
  }
}

some.module.js (output)

const pathData = require('./assets/some.source.svg')

  // The match function returned the first (and only) capture group,
  // so the final matches array contains only those items.
  [
    'M387 0l387 218.9v437.9L387...',
    'M704.9 641.7L399.8 814...',
    'M373 649.3L185.4 546....'
  ]

Using project

The project option can be used to modify the final result after all matches have been processed. It receives a list of items if the g (global) flag was specified in the regex, or a single item if g was not specified. The result passed to project will be whatever form was returned from match. If match is not used, the result passed to project will be either a list of RegExp match objects or a single one, depending on whether the regex was global or not.

some.source.svg (input)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3046.7 875.7">
  <title>webpack-logo</title>
  <path class="back" fill="#FFF" d="M387 0l387 218.9v437.9L387..."/>
  <path class="outer" fill="#8ED6FB" d="M704.9 641.7L399.8 814..."/>
  <path class="inner" fill="#1C78C0" d="M373 649.3L185.4 546...."/>
</svg>

webpack.config.js (config)

module.exports = {
  ...,
  module: {
    rules: [{
      test: /\.source.svg$/,
      use: {
        loader: 'regex-extract-loader',
        options: {
          regex: 'path.+\\bd="(.+?)"',
          flags: 'g'
          // Transform each item in the match object into another form.
          project: (result) => {
            return result.map((match) => {
              return { path: match[1], index: match.index }
            })
          }
        }
      }
    }]
  }
}

some.module.js (output)

const pathData = require('./assets/some.source.svg')

  // The project function returned a list of custom objects.
  [
    { path: 'M387 0l387 218.9v437.9L387...', index: 101 },
    { path: 'M704.9 641.7L399.8 814...', index: 170 },
    { path: 'M373 649.3L185.4 546....', index: 239 }
  ]

Examples

Extract release information from a change log

changelog.md (input)

## [2.0.0] - 2017-11-20
New version

## [1.0.1] - 2017-11-07
Fix stuff

## [1.0.0] - 2017-11-05
Initial release

webpack.config.js (config)

module.exports = {
  ...,
  module: {
    rules: [{
      test: /changelog.md$/,
      use: {
        loader: 'regex-extract-loader',
        options: {
          regex: '\\s*## \\[(.+)\\] - (\\d{4}-\\d{2}-\\d{2})\n(.+)',
          flags: 'g',
          match: (match) => ({
            version: match[1], date: match[2], note: match[3]
          })
        }
      }
    }]
  }
}

some.module.js (output)

const versions = require('./changelog.md')

  [
    { version: '2.0.0', date: '2017-11-20', note: 'New version' },
    { version: '1.0.1', date: '2017-11-07', note: 'Fix stuff' },
    { version: '1.0.0', date: '2017-11-05', note: 'Initial release' }
  ]

Parse key/value pairs from a source in key=value format

some.source.cfg (input)

name=Nebula
rank=10
attributes=["female", "blue", "cybernetic", "angry", "nebulicious"]

webpack.config.js (config)

module.exports = {
  ...,
  module: {
    rules: [{
      test: /\.source.cfg$/,
      use: {
        loader: 'regex-extract-loader',
        options: {
          regex: '^(.+)=(.+)$',
          flags: 'mg',
          match: (match) => ({ key: match[1], value: match[2] }),
          project: (result) => {
            return result.reduce((map, item) => {
              try {
                map[item.key] = JSON.parse(item.value)
              } catch (e) {
                map[item.key] = item.value
              }
              return map
            }, {})
          }
        }
      }
    }]
  }
}

some.module.js (output)

const cfg = require('./assets/some.source.cfg')

{
  name: 'Nebula',
  rank: 10,
  attributes: [ 'female', 'blue', 'cybernetic', 'angry', 'nebulicious' ]
}

Other Examples

See the match and project unit tests for additional examples.