master 34a9dddc1813 cached
34 files
94.1 KB
24.4k tokens
52 symbols
1 requests
Download .txt
Repository: VerbalExpressions/JSVerbalExpressions
Branch: master
Commit: 34a9dddc1813
Files: 34
Total size: 94.1 KB

Directory structure:
gitextract_ziqoi740/

├── .editorconfig
├── .eslintrc
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── automerge.yml
│       ├── codeql-analysis.yml
│       ├── gh-pages.yml
│       └── test.yml
├── .gitignore
├── .mdlintrc.json
├── Gruntfile.js
├── LICENSE
├── README.md
├── VerbalExpressions.js
├── bower.json
├── dist/
│   └── verbalexpressions.js
├── docs/
│   ├── 404.md
│   ├── Gemfile
│   ├── VerEx.md
│   ├── VerbalExpression/
│   │   ├── capture-groups.md
│   │   ├── constructor.md
│   │   ├── index.md
│   │   ├── loops.md
│   │   ├── miscellaneous.md
│   │   ├── modifiers.md
│   │   ├── rules.md
│   │   ├── special-characters.md
│   │   └── utilities.md
│   ├── _config.yml
│   ├── _layouts/
│   │   └── default.html
│   ├── assets/
│   │   └── css/
│   │       └── style.scss
│   └── index.md
├── package.json
├── test/
│   └── tests.js
└── typings/
    └── VerbalExpressions.d.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
    end_of_line = lf
    trim_trailing_whitespace = true
    insert_final_newline = true
    indent_style = space
    indent_size = 4
    charset = utf8

[{package.json, package-lock.json}]
    indent_size = 2


================================================
FILE: .eslintrc
================================================
{
    "extends": "airbnb",
    "rules": {
        "indent": [2, 4],
        "no-underscore-dangle": [2, { "allowAfterThis": true }],
        "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"],
        "newline-per-chained-call": "off",
        "max-len": [2, 255, 4],
        "no-param-reassign": 0,
        "spaced-comment": [2, "always", { "markers": ["/", "!"] }],
        "no-plusplus": 0,
        "operator-linebreak":"off"
    },
    "env": {
        "amd": true,
        "node": true,
        "commonjs": true,
        "es6": true,
        "browser": true
    },
    "globals": {
        "VerEx": true
    }
}


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule:
      interval: daily
    open-pull-requests-limit: 1000000
  - package-ecosystem: bundler
    directory: "/docs"
    schedule:
      interval: daily
    open-pull-requests-limit: 1000000


================================================
FILE: .github/workflows/automerge.yml
================================================
name: Dependabot auto-merge
on: pull_request

permissions:
  pull-requests: write
  contents: write

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: ${{ github.actor == 'dependabot[bot]' }}
    steps:
      - name: Enable auto-merge for Dependabot PRs
        env:
          PR_URL: ${{github.event.pull_request.html_url}}
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
        run: |
          function get_pending_jobs() {
            gh pr view "$PR_URL" --json statusCheckRollup --jq '.statusCheckRollup | map(select(.name != "dependabot")) | map(select(.status != "COMPLETED")).[]'
          }

          function get_failed_jobs() {
            gh pr view "$PR_URL" --json statusCheckRollup --jq '.statusCheckRollup | map(select(.name != "dependabot")) | map(select(.conclusion != "SUCCESS")).[]'
          }

          function wait_until_completed() {
            while [[ $(get_pending_jobs) ]]
            do
              sleep 5
            done
          }

          function fail_if_unsuccessful() {
            if [[ $(get_failed_jobs) ]]; then
              echo "Some jobs failed, unable to automerge"
              exit 1
            fi
          }

          function auto_merge() {
            gh pr merge --auto --rebase "$PR_URL"
          }

          wait_until_completed && \
          fail_if_unsuccessful && \
          auto_merge


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: 'CodeQL'

on:
    push:
        branches: [master]
    pull_request:
        # The branches below must be a subset of the branches above
        branches: [master]
    schedule:
        - cron: '33 0 * * 1'

jobs:
    analyze:
        name: Analyze
        runs-on: ubuntu-latest

        strategy:
            fail-fast: false
            matrix:
                language: ['javascript']
                # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
                # Learn more:
                # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

        steps:
            - name: Checkout repository
              uses: actions/checkout@v2

            # Initializes the CodeQL tools for scanning.
            - name: Initialize CodeQL
              uses: github/codeql-action/init@v1
              with:
                  languages: ${{ matrix.language }}
                  # If you wish to specify custom queries, you can do so here or in a config file.
                  # By default, queries listed here will override any specified in a config file.
                  # Prefix the list here with "+" to use these queries and those in the config file.
                  # queries: ./path/to/local/query, your-org/your-repo/queries@main

            # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
            # If this step fails, then you should remove it and run the build manually (see below)
            - name: Autobuild
              uses: github/codeql-action/autobuild@v1

            # ℹ️ Command-line programs to run using the OS shell.
            # 📚 https://git.io/JvXDl

            # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
            #    and modify them (or add more) to build your code if your project
            #    uses a compiled language

            #- run: |
            #   make bootstrap
            #   make release

            - name: Perform CodeQL Analysis
              uses: github/codeql-action/analyze@v1


================================================
FILE: .github/workflows/gh-pages.yml
================================================
name: Build docs/ folder
on: pull_request
jobs:
    test:
        name: Build docs/ folder
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v2
            - uses: actions/setup-ruby@v1
            - run: |
                  cd docs
                  gem install bundler --version '~> 1'
                  bundle install
                  bundle exec jekyll build
            - run: |
                  git add -A                      # Make sure new files are accounted
                  git diff --exit-code --cached   # Expect no changes in git


================================================
FILE: .github/workflows/test.yml
================================================
name: Run tests
on: pull_request
jobs:
    test:
        name: Run tests on Node.js ${{ matrix.node-version }}
        runs-on: ubuntu-latest
        strategy:
            matrix:
                node-version: ["16", "15", "14", "13", "12"]
        steps:
            - uses: actions/checkout@v2
            - uses: actions/setup-node@v1
              with:
                  node-version: ${{ matrix.node-version }}
            - run: npm ci
            - run: npm run test:verbose


================================================
FILE: .gitignore
================================================
node_modules
.DS_Store
.idea/
.vscode/
.nyc_output
docs/_site
docs/.sass-cache
docs/.jekyll-metadata


================================================
FILE: .mdlintrc.json
================================================
{
    "heading-increment": true,
    "first-heading-h1": { "level": 1 },
    "heading-style": { "style": "atx" },
    "ul-style": { "style": "dash" },
    "list-indent": true,
    "ul-start-left": true,
    "ul-indent": { "indent": 4 },
    "no-trailing-spaces": true,
    "no-hard-tabs": true,
    "no-reversed-links": true,
    "no-multiple-blanks": { "maximum": 1 },
    "line-length": false,
    "commands-show-output": true,
    "no-missing-space-atx": true,
    "no-multiple-space-atx": true,
    "no-missing-space-closed-atx": true,
    "no-multiple-space-closed-atx": true,
    "blanks-around-headings": true,
    "heading-start-left": true,
    "no-duplicate-heading": true,
    "single-h1": false,
    "no-trailing-punctuation": true,
    "ol-prefix": { "style": "ordered" },
    "list-marker-space": 1,
    "blanks-around-fences": true,
    "blanks-around-lists": true,
    "no-inline-html": false,
    "no-bare-urls": true,
    "hr-style": { "style": "___" },
    "no-emphasis-as-heading": true,
    "no-space-in-emphasis": true,
    "no-space-in-code": false,
    "no-space-in-links": true,
    "fenced-code-language": false,
    "first-line-h1": true,
    "no-empty-links": true,
    "no-alt-text": true
}


================================================
FILE: Gruntfile.js
================================================
module.exports = function gruntConfig(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        eslint: {
            target: ['VerbalExpressions.js', 'test/tests.js', 'Gruntfile.js'],
        },

        ava: {
            test: ['test/tests.js'],
            options: {
                nyc: true,
            },

            verbose: {
                test: ['test/tests.js'],
                options: {
                    verbose: true,
                    nyc: true,
                },
            },
        },

        babel: {
            options: {
                sourceMap: true,
                presets: [['@babel/preset-env', { modules: false }]],
                plugins: [
                    ['transform-builtin-extend', { globals: ['RegExp'] }],
                ],
            },
            dist: {
                files: {
                    'dist/verbalexpressions.js': 'VerbalExpressions.js',
                },
            },
        },

        umd: {
            all: {
                options: {
                    src: 'dist/verbalexpressions.js',
                    objectToExport: 'VerEx',
                    amdModuleId: 'VerEx',
                    globalAlias: 'VerEx',
                },
            },
        },

        uglify: {
            options: {
                banner:
                    '/*!\n' +
                    '* <%= pkg.name %> JavaScript Library v<%= pkg.version %>\n' +
                    '* <%= pkg.homepage %>\n' +
                    '*\n' +
                    '* Released under the <%= pkg.license %> license\n' +
                    '*/\n',
                sourceMap: true,
            },
            dist: {
                files: {
                    'dist/verbalexpressions.min.js': [
                        'dist/verbalexpressions.js',
                    ],
                },
            },
        },

        sourcemap_localize: {
            options: {
                localize_to: '..',
            },
            build: {
                files: {
                    src: ['dist/*.min.js.map'],
                },
            },
        },

        markdownlint: {
            options: {
                config: grunt.file.readJSON('.mdlintrc.json'),
            },
            src: ['README.md', 'docs/*.md', 'docs/VerbalExpression/*.md'],
        },
    });

    grunt.loadNpmTasks('grunt-eslint');
    grunt.loadNpmTasks('grunt-ava');
    grunt.loadNpmTasks('grunt-babel');
    grunt.loadNpmTasks('grunt-umd');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-sourcemap-localize');
    grunt.loadNpmTasks('grunt-markdownlint');

    grunt.registerTask('default', ['test']);
    grunt.registerTask('test', [
        'compile',
        'eslint',
        'markdownlint',
        'ava:test',
    ]);
    grunt.registerTask('test:verbose', ['compile', 'eslint', 'ava:verbose']);
    grunt.registerTask('compile', ['babel', 'umd:all']);
    grunt.registerTask('build', [
        'compile',
        'ava:test',
        'uglify',
        'sourcemap_localize',
    ]);
};


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2017 jehna

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# VerbalExpressions

[![Build Status](https://travis-ci.org/VerbalExpressions/JSVerbalExpressions.svg)](https://travis-ci.org/VerbalExpressions/JSVerbalExpressions)
[![Latest Version](https://img.shields.io/npm/v/verbal-expressions.svg)](https://www.npmjs.com/package/verbal-expressions)
[![jsDelivr](https://img.shields.io/badge/dynamic/json.svg?label=jsDelivr&url=https%3A%2F%2Fdata.jsdelivr.com%2Fv1%2Fpackage%2Fnpm%2Fverbal-expressions&query=%24..tags.latest&colorB=blue&prefix=v)](https://www.jsdelivr.com/package/npm/verbal-expressions)
[![License](https://img.shields.io/github/license/VerbalExpressions/JSVerbalExpressions.svg)](LICENSE)

## JavaScript Regular Expressions made easy

VerbalExpressions is a JavaScript library that helps construct difficult regular expressions.

## How to get started

### In the browser

```html
<script src="VerbalExpressions.js"></script>
```

Or use the [jsDelivr CDN](https://www.jsdelivr.com/package/npm/verbal-expressions).

### On the server (node.js)

Install:

```sh
npm install verbal-expressions
```

Require:

```js
const VerEx = require('verbal-expressions');
```

Or use ES6's `import`:

```js
import VerEx from 'verbal-expressions';
```

## Running tests

```sh
npm test
```

(or)

```sh
npm run test:verbose
```

## Creating a minified version

```sh
npm run build
```

This will run [Babel](https://babeljs.io) on `VerbalExpressions.js` and output the result to `dist/verbalexpressions.js`. A minified version of the same will also be written to `dist/verbalexpressions.min.js`.

A source map will also be created in `dist`, so you can use the original "un-babelified", unminified source file for debugging purposes.

## Building the docs/ folder

The `docs/` folder uses Jekyll for building the static HTML and is hosted at
gh-pages.

To install the Ruby dependencies, run:

```
cd docs/
bundle install
```

This installs all needed Ruby dependencies locally

After you've installed dependencies, you can run:

```
bundle exec jekyll build
```

This builds all static files to `docs/_site/` folder.

If you want to develop the files locally, you can run:

```
bundle exec jekyll serve
```

This starts a local development web server and starts watching your files for
changes.

## API documentation

You can find the API documentation at [verbalexpressions.github.io/JSVerbalExpressions](https://verbalexpressions.github.io/JSVerbalExpressions). You can find the source code for the docs in [`docs`](docs/).

## Examples

Here are some simple examples to give an idea of how VerbalExpressions works:

### Testing if we have a valid URL

```js
// Create an example of how to test for correctly formed URLs
const tester = VerEx()
    .startOfLine()
    .then('http')
    .maybe('s')
    .then('://')
    .maybe('www.')
    .anythingBut(' ')
    .endOfLine();

// Create an example URL
const testMe = 'https://www.google.com';

// Use RegExp object's native test() function
if (tester.test(testMe)) {
    alert('We have a correct URL'); // This output will fire
} else {
    alert('The URL is incorrect');
}

console.log(tester); // Outputs the actual expression used: /^(http)(s)?(\:\/\/)(www\.)?([^\ ]*)$/
```

### Replacing strings

```js
// Create a test string
const replaceMe = 'Replace bird with a duck';

// Create an expression that seeks for word "bird"
const expression = VerEx().find('bird');

// Execute the expression like a normal RegExp object
const result = expression.replace(replaceMe, 'duck');

// Outputs "Replace duck with a duck"
alert(result);
```

### Shorthand for string replace

```js
const result = VerEx().find('red').replace('We have a red house', 'blue');

// Outputs "We have a blue house"
alert(result);
```

## Contributions

Pull requests are warmly welcome!

Clone the repo and fork:

```sh
git clone https://github.com/VerbalExpressions/JSVerbalExpressions.git
```

### Style guide

The [Airbnb](https://github.com/airbnb/javascript) style guide is loosely used as a basis for creating clean and readable JavaScript code. Check [`.eslintrc`](.eslintrc).

Check out these slide decks for handy Github & git tips:

- [Git and Github Secrets](https://zachholman.com/talk/git-github-secrets/)
- [More Git and Github Secrets](https://zachholman.com/talk/more-git-and-github-secrets/)

## Tools

- <https://verbalregex.com> - it's a wrapper of JSVerbalExpressions; users can write down the code and compile to regex
- <https://jsbin.com/metukuzowi/edit?js,console> - JSBin Playground

## Other Implementations

You can see an up to date list of all ports on [VerbalExpressions.github.io](https://VerbalExpressions.github.io).

- [Ruby](https://github.com/ryan-endacott/verbal_expressions)
- [C#](https://github.com/VerbalExpressions/CSharpVerbalExpressions)
- [Python](https://github.com/VerbalExpressions/PythonVerbalExpressions)
- [Java](https://github.com/VerbalExpressions/JavaVerbalExpressions)
- [Groovy](https://github.com/VerbalExpressions/GroovyVerbalExpressions)
- [PHP](https://github.com/VerbalExpressions/PHPVerbalExpressions)
- [Haskell](https://github.com/VerbalExpressions/HaskellVerbalExpressions)
- [Haxe](https://github.com/VerbalExpressions/HaxeVerbalExpressions)
- [C++](https://github.com/VerbalExpressions/CppVerbalExpressions)
- [Objective-C](https://github.com/VerbalExpressions/ObjectiveCVerbalExpressions)
- [Perl](https://github.com/VerbalExpressions/PerlVerbalExpressions)
- [Swift](https://github.com/VerbalExpressions/SwiftVerbalExpressions)

If you would like to contribute another port (which would be awesome!), please [open an issue](https://github.com/VerbalExpressions/implementation/issues/new) specifying the language in the [VerbalExpressions/implementation repo](https://github.com/VerbalExpressions/implementation/issues). Please don't open PRs for other languages against this repo.

### Similar projects

Here's a list of other similar projects that implement regular expression
builders:

- https://github.com/MaxArt2501/re-build
- https://github.com/mathiasbynens/regenerate

================================================
FILE: VerbalExpressions.js
================================================
/**
 * @file VerbalExpressions JavaScript Library
 * @version 0.3.0
 * @license MIT
 *
 * @see https://github.com/VerbalExpressions/JSVerbalExpressions
 */

/**
 * Define the VerbalExpression class
 *
 * @class VerbalExpression
 * @extends {RegExp}
 */
class VerbalExpression extends RegExp {
    /**
     * Creates an instance of VerbalExpression.
     * @constructor
     * @alias VerEx
     * @memberof VerbalExpression
     */
    constructor() {
        // Call the `RegExp` constructor so that `this` can be used
        super('', 'gm');

        // Variables to hold the expression construction in order
        this._prefixes = '';
        this._source = '';
        this._suffixes = '';
        this._modifiers = 'gm'; // 'global, multiline' matching by default
    }

    // Utility //

    /**
     * Escape meta-characters in the parameter and make it safe for adding to the expression
     * @static
     * @param {(string|RegExp|number)} value object to sanitize
     * @returns {string} sanitized value
     * @memberof VerbalExpression
     */
    static sanitize(value) {
        if (value instanceof RegExp) {
            return value.source;
        }

        if (typeof value === 'number') {
            return value;
        }

        if (typeof value !== 'string') {
            return '';
        }

        // Regular expression to match meta characters
        // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp
        const toEscape = /([\].|*?+(){}^$\\:=[])/g;

        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch
        const lastMatch = '$&';

        // Escape meta characters
        return value.replace(toEscape, `\\${lastMatch}`);
    }

    /**
     * Add stuff to the expression and compile the new expression so it's ready to be used.
     * @param {(string|number)} [value=''] stuff to add
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    add(value = '') {
        this._source += value;
        const pattern = this._prefixes + this._source + this._suffixes;

        this.compile(pattern, this._modifiers);

        return this;
    }

    // Rules //

    /**
     * Control start-of-line matching
     * @param {boolean} [enable=true] whether to enable this behaviour
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    startOfLine(enable = true) {
        this._prefixes = enable ? '^' : '';
        return this.add();
    }

    /**
     * Control end-of-line matching
     * @param {boolean} [enable=true] whether to enable this behaviour
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    endOfLine(enable = true) {
        this._suffixes = enable ? '$' : '';
        return this.add();
    }

    /**
     * Look for the value passed
     * @param {(string|RegExp|number)} value value to find
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    then(value) {
        value = VerbalExpression.sanitize(value);
        return this.add(`(?:${value})`);
    }

    /**
     * Alias for then() to allow for readable syntax when then() is the first method in the chain.
     * @param {(string|RegExp|numer)} value value to find
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    find(value) {
        return this.then(value);
    }

    /**
     * Add optional values
     * @param {(string|RegExp|number)} value value to find
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    maybe(value) {
        value = VerbalExpression.sanitize(value);
        return this.add(`(?:${value})?`);
    }

    /**
     * Add alternative expressions
     * @param {(string|RegExp|number)} value value to find
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    or(value) {
        this._prefixes += '(?:';
        this._suffixes = `)${this._suffixes}`;

        this.add(')|(?:');

        if (value) {
            this.then(value);
        }

        return this;
    }

    /**
     * Any character any number of times
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    anything() {
        return this.add('(?:.*)');
    }

    /**
     * Anything but these characters
     * @param {(string|number|string[]|number[])} value characters to not match
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    anythingBut(value) {
        if (Array.isArray(value)) {
            value = value.join('');
        }

        value = VerbalExpression.sanitize(value);
        return this.add(`(?:[^${value}]*)`);
    }

    /**
     * Any character(s) at least once
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    something() {
        return this.add('(?:.+)');
    }

    /**
     * Any character at least one time except for these characters
     * @param {(string|number|string[]|number[])} value characters to not match
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    somethingBut(value) {
        if (Array.isArray(value)) {
            value = value.join('');
        }

        value = VerbalExpression.sanitize(value);
        return this.add(`(?:[^${value}]+)`);
    }

    /**
     * Match any of the given characters
     * @param {(string|number|string[]|number[])} value characters to match
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    anyOf(value) {
        if (Array.isArray(value)) {
            value = value.join('');
        }

        value = VerbalExpression.sanitize(value);
        return this.add(`[${value}]`);
    }

    /**
     * Shorthand for anyOf(value)
     * @param {string|number} value value to find
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    any(value) {
        return this.anyOf(value);
    }

    /**
     * Ensure that the parameter does not follow
     * @param {string|number} value
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    not(value) {
        value = VerbalExpression.sanitize(value);
        this.add(`(?!${value})`);

        return this;
    }

    /**
     * Matching any character within a range of characters
     * Usage: .range( from, to [, from, to ... ] )
     * @param {...string} ranges characters denoting beginning and ending of ranges
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    range(...ranges) {
        let value = '';

        for (let i = 1; i < ranges.length; i += 2) {
            const from = VerbalExpression.sanitize(ranges[i - 1]);
            const to = VerbalExpression.sanitize(ranges[i]);

            value += `${from}-${to}`;
        }

        return this.add(`[${value}]`);
    }

    // Special characters //

    /**
     * Match a Line break
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    lineBreak() {
        return this.add('(?:\\r\\n|\\r|\\n)'); // Unix(LF) + Windows(CRLF)
    }

    /**
     * A shorthand for lineBreak() for html-minded users
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    br() {
        return this.lineBreak();
    }

    /**
     * Match a tab character
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    tab() {
        return this.add('\\t');
    }

    /**
     * Match any alphanumeric
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    word() {
        return this.add('\\w+');
    }

    /**
     * Match a single digit
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    digit() {
        return this.add('\\d');
    }

    /**
     * Match a single whitespace
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    whitespace() {
        return this.add('\\s');
    }

    // Modifiers //

    /**
     * Add a regex modifier/flag
     * @param {string} modifier modifier to add
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    addModifier(modifier) {
        if (!this._modifiers.includes(modifier)) {
            this._modifiers += modifier;
        }

        return this.add();
    }

    /**
     * Remove modifier
     * @param {string} modifier modifier to remove
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    removeModifier(modifier) {
        this._modifiers = this._modifiers.replace(modifier, '');
        return this.add();
    }

    /**
     * Control case-insensitive matching
     * @param {boolean} [enable=true] whether to enable this behaviour
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    withAnyCase(enable = true) {
        return enable ? this.addModifier('i') : this.removeModifier('i');
    }

    /**
     * Default behaviour is with "g" modifier, so we can turn this another way around than other modifiers
     * @param {boolean} [enable=true] whether to enable this behaviour
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    stopAtFirst(enable = true) {
        return enable ? this.removeModifier('g') : this.addModifier('g');
    }

    /**
     * Control the multiline modifier
     * @param {boolean} [enable=true] whether to enable this behaviour
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    searchOneLine(enable = true) {
        return enable ? this.removeModifier('m') : this.addModifier('m');
    }

    // Loops //

    /**
     * Repeat the previous item exactly n times or between n and m times
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    repeatPrevious(...quantity) {
        const isInteger = /\d+/;
        const values = quantity.filter((argument) => isInteger.test(argument));

        if (values.length === 0 || values.length > 2) {
            return this;
        }

        this.add(`{${values.join(',')}}`);

        return this;
    }

    /**
     * Repeat the previous at least once
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    oneOrMore() {
        return this.add('+');
    }

    /**
     * Match the value zero or more times
     * @param {string} value value to find
     * @param {integer} [lower] minimum number of times the value should be repeated
     * @param {integer} [upper] maximum number of times the value should be repeated
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    multiple(value, lower, upper) {
        if (value !== undefined) {
            value = VerbalExpression.sanitize(value);
            this.add(`(?:${value})`);
        }

        if (lower === undefined && upper === undefined) {
            this.add('*'); // Any number of times
        } else if (lower !== undefined && upper === undefined) {
            this.add(`{${lower},}`);
        } else if (lower !== undefined && upper !== undefined) {
            this.add(`{${lower},${upper}}`);
        }

        return this;
    }

    // Capture groups //

    /**
     * Starts a capturing group
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    beginCapture() {
        // Add the end of the capture group to the suffixes temporarily so that compilation continues to work
        this._suffixes += ')';
        return this.add('(');
    }

    /**
     * Ends a capturing group
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    endCapture() {
        // Remove the last parenthesis from the _suffixes and add it to the regex
        this._suffixes = this._suffixes.slice(0, -1);
        return this.add(')');
    }

    // Miscellaneous //

    /**
     * Shorthand function for the string.replace function to allow for a more logical flow
     * @param {string} source string to search for
     * @param {string} value value to replace with
     * @returns {VerbalExpression} recompiled instance of VerbalExpression
     * @memberof VerbalExpression
     */
    replace(source, value) {
        source = source.toString();
        return source.replace(this, value);
    }

    /**
     * Convert to RegExp object
     * @returns {RegExp} equivalent RegExp instance
     * @memberof VerbalExpression
     */
    toRegExp() {
        const components = this.toString().match(/\/(.*)\/([gimuy]+)?/);
        const pattern = components[1];
        const flags = components[2];

        return new RegExp(pattern, flags);
    }
}

/**
 * Return a new instance of `VerbalExpression`
 * @export
 * @returns {VerbalExpression} new instance
 */
function VerEx() { // eslint-disable-line no-unused-vars
    const instance = new VerbalExpression();
    instance.sanitize = VerbalExpression.sanitize;
    return instance;
}


================================================
FILE: bower.json
================================================
{
    "name": "verbal-expressions",
    "description": "JavaScript Regular expressions made easy",
    "keywords": [ "regular expressions", "regex" ],
    "main": "dist/verbalexpressions.js",
    "license": "MIT",
    "ignore": [
        "**/.*",
        "node_modules",
        "bower_components",
        "test",
        "tests",
        "Gruntfile.js",
        "package.json",
        "bower.json"
    ]
}


================================================
FILE: dist/verbalexpressions.js
================================================
(function (root, factory) {
  if (root === undefined && window !== undefined) root = window;
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module unless amdModuleId is set
    define('VerEx', [], function () {
      return (root['VerEx'] = factory());
    });
  } else if (typeof module === 'object' && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    root['VerEx'] = factory();
  }
}(this, function () {

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _extendableBuiltin(cls) {
    function ExtendableBuiltin() {
        var instance = Reflect.construct(cls, Array.from(arguments));
        Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
        return instance;
    }

    ExtendableBuiltin.prototype = Object.create(cls.prototype, {
        constructor: {
            value: cls,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });

    if (Object.setPrototypeOf) {
        Object.setPrototypeOf(ExtendableBuiltin, cls);
    } else {
        ExtendableBuiltin.__proto__ = cls;
    }

    return ExtendableBuiltin;
}

/**
 * @file VerbalExpressions JavaScript Library
 * @version 0.3.0
 * @license MIT
 *
 * @see https://github.com/VerbalExpressions/JSVerbalExpressions
 */

/**
 * Define the VerbalExpression class
 *
 * @class VerbalExpression
 * @extends {RegExp}
 */
var VerbalExpression = function (_extendableBuiltin2) {
    _inherits(VerbalExpression, _extendableBuiltin2);

    /**
     * Creates an instance of VerbalExpression.
     * @constructor
     * @alias VerEx
     * @memberof VerbalExpression
     */
    function VerbalExpression() {
        _classCallCheck(this, VerbalExpression);

        // Variables to hold the expression construction in order
        var _this = _possibleConstructorReturn(this, (VerbalExpression.__proto__ || Object.getPrototypeOf(VerbalExpression)).call(this, '', 'gm'));
        // Call the `RegExp` constructor so that `this` can be used


        _this._prefixes = '';
        _this._source = '';
        _this._suffixes = '';
        _this._modifiers = 'gm'; // 'global, multiline' matching by default
        return _this;
    }

    // Utility //

    /**
     * Escape meta-characters in the parameter and make it safe for adding to the expression
     * @static
     * @param {(string|RegExp|number)} value object to sanitize
     * @returns {string} sanitized value
     * @memberof VerbalExpression
     */


    _createClass(VerbalExpression, [{
        key: 'add',


        /**
         * Add stuff to the expression and compile the new expression so it's ready to be used.
         * @param {(string|number)} [value=''] stuff to add
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */
        value: function add() {
            var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';

            this._source += value;
            var pattern = this._prefixes + this._source + this._suffixes;

            this.compile(pattern, this._modifiers);

            return this;
        }

        // Rules //

        /**
         * Control start-of-line matching
         * @param {boolean} [enable=true] whether to enable this behaviour
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'startOfLine',
        value: function startOfLine() {
            var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

            this._prefixes = enable ? '^' : '';
            return this.add();
        }

        /**
         * Control end-of-line matching
         * @param {boolean} [enable=true] whether to enable this behaviour
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'endOfLine',
        value: function endOfLine() {
            var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

            this._suffixes = enable ? '$' : '';
            return this.add();
        }

        /**
         * Look for the value passed
         * @param {(string|RegExp|number)} value value to find
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'then',
        value: function then(value) {
            value = VerbalExpression.sanitize(value);
            return this.add('(?:' + value + ')');
        }

        /**
         * Alias for then() to allow for readable syntax when then() is the first method in the chain.
         * @param {(string|RegExp|numer)} value value to find
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'find',
        value: function find(value) {
            return this.then(value);
        }

        /**
         * Add optional values
         * @param {(string|RegExp|number)} value value to find
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'maybe',
        value: function maybe(value) {
            value = VerbalExpression.sanitize(value);
            return this.add('(?:' + value + ')?');
        }

        /**
         * Add alternative expressions
         * @param {(string|RegExp|number)} value value to find
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'or',
        value: function or(value) {
            this._prefixes += '(?:';
            this._suffixes = ')' + this._suffixes;

            this.add(')|(?:');

            if (value) {
                this.then(value);
            }

            return this;
        }

        /**
         * Any character any number of times
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'anything',
        value: function anything() {
            return this.add('(?:.*)');
        }

        /**
         * Anything but these characters
         * @param {(string|number|string[]|number[])} value characters to not match
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'anythingBut',
        value: function anythingBut(value) {
            if (Array.isArray(value)) {
                value = value.join('');
            }

            value = VerbalExpression.sanitize(value);
            return this.add('(?:[^' + value + ']*)');
        }

        /**
         * Any character(s) at least once
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'something',
        value: function something() {
            return this.add('(?:.+)');
        }

        /**
         * Any character at least one time except for these characters
         * @param {(string|number|string[]|number[])} value characters to not match
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'somethingBut',
        value: function somethingBut(value) {
            if (Array.isArray(value)) {
                value = value.join('');
            }

            value = VerbalExpression.sanitize(value);
            return this.add('(?:[^' + value + ']+)');
        }

        /**
         * Match any of the given characters
         * @param {(string|number|string[]|number[])} value characters to match
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'anyOf',
        value: function anyOf(value) {
            if (Array.isArray(value)) {
                value = value.join('');
            }

            value = VerbalExpression.sanitize(value);
            return this.add('[' + value + ']');
        }

        /**
         * Shorthand for anyOf(value)
         * @param {string|number} value value to find
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'any',
        value: function any(value) {
            return this.anyOf(value);
        }

        /**
         * Ensure that the parameter does not follow
         * @param {string|number} value
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'not',
        value: function not(value) {
            value = VerbalExpression.sanitize(value);
            this.add('(?!' + value + ')');

            return this;
        }

        /**
         * Matching any character within a range of characters
         * Usage: .range( from, to [, from, to ... ] )
         * @param {...string} ranges characters denoting beginning and ending of ranges
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'range',
        value: function range() {
            var value = '';

            for (var i = 1; i < arguments.length; i += 2) {
                var from = VerbalExpression.sanitize(arguments.length <= i - 1 ? undefined : arguments[i - 1]);
                var to = VerbalExpression.sanitize(arguments.length <= i ? undefined : arguments[i]);

                value += from + '-' + to;
            }

            return this.add('[' + value + ']');
        }

        // Special characters //

        /**
         * Match a Line break
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'lineBreak',
        value: function lineBreak() {
            return this.add('(?:\\r\\n|\\r|\\n)'); // Unix(LF) + Windows(CRLF)
        }

        /**
         * A shorthand for lineBreak() for html-minded users
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'br',
        value: function br() {
            return this.lineBreak();
        }

        /**
         * Match a tab character
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'tab',
        value: function tab() {
            return this.add('\\t');
        }

        /**
         * Match any alphanumeric
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'word',
        value: function word() {
            return this.add('\\w+');
        }

        /**
         * Match a single digit
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'digit',
        value: function digit() {
            return this.add('\\d');
        }

        /**
         * Match a single whitespace
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'whitespace',
        value: function whitespace() {
            return this.add('\\s');
        }

        // Modifiers //

        /**
         * Add a regex modifier/flag
         * @param {string} modifier modifier to add
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'addModifier',
        value: function addModifier(modifier) {
            if (!this._modifiers.includes(modifier)) {
                this._modifiers += modifier;
            }

            return this.add();
        }

        /**
         * Remove modifier
         * @param {string} modifier modifier to remove
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'removeModifier',
        value: function removeModifier(modifier) {
            this._modifiers = this._modifiers.replace(modifier, '');
            return this.add();
        }

        /**
         * Control case-insensitive matching
         * @param {boolean} [enable=true] whether to enable this behaviour
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'withAnyCase',
        value: function withAnyCase() {
            var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

            return enable ? this.addModifier('i') : this.removeModifier('i');
        }

        /**
         * Default behaviour is with "g" modifier, so we can turn this another way around than other modifiers
         * @param {boolean} [enable=true] whether to enable this behaviour
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'stopAtFirst',
        value: function stopAtFirst() {
            var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

            return enable ? this.removeModifier('g') : this.addModifier('g');
        }

        /**
         * Control the multiline modifier
         * @param {boolean} [enable=true] whether to enable this behaviour
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'searchOneLine',
        value: function searchOneLine() {
            var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;

            return enable ? this.removeModifier('m') : this.addModifier('m');
        }

        // Loops //

        /**
         * Repeat the previous item exactly n times or between n and m times
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'repeatPrevious',
        value: function repeatPrevious() {
            var isInteger = /\d+/;

            for (var _len = arguments.length, quantity = Array(_len), _key = 0; _key < _len; _key++) {
                quantity[_key] = arguments[_key];
            }

            var values = quantity.filter(function (argument) {
                return isInteger.test(argument);
            });

            if (values.length === 0 || values.length > 2) {
                return this;
            }

            this.add('{' + values.join(',') + '}');

            return this;
        }

        /**
         * Repeat the previous at least once
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'oneOrMore',
        value: function oneOrMore() {
            return this.add('+');
        }

        /**
         * Match the value zero or more times
         * @param {string} value value to find
         * @param {integer} [lower] minimum number of times the value should be repeated
         * @param {integer} [upper] maximum number of times the value should be repeated
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'multiple',
        value: function multiple(value, lower, upper) {
            if (value !== undefined) {
                value = VerbalExpression.sanitize(value);
                this.add('(?:' + value + ')');
            }

            if (lower === undefined && upper === undefined) {
                this.add('*'); // Any number of times
            } else if (lower !== undefined && upper === undefined) {
                this.add('{' + lower + ',}');
            } else if (lower !== undefined && upper !== undefined) {
                this.add('{' + lower + ',' + upper + '}');
            }

            return this;
        }

        // Capture groups //

        /**
         * Starts a capturing group
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'beginCapture',
        value: function beginCapture() {
            // Add the end of the capture group to the suffixes temporarily so that compilation continues to work
            this._suffixes += ')';
            return this.add('(');
        }

        /**
         * Ends a capturing group
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'endCapture',
        value: function endCapture() {
            // Remove the last parenthesis from the _suffixes and add it to the regex
            this._suffixes = this._suffixes.slice(0, -1);
            return this.add(')');
        }

        // Miscellaneous //

        /**
         * Shorthand function for the string.replace function to allow for a more logical flow
         * @param {string} source string to search for
         * @param {string} value value to replace with
         * @returns {VerbalExpression} recompiled instance of VerbalExpression
         * @memberof VerbalExpression
         */

    }, {
        key: 'replace',
        value: function replace(source, value) {
            source = source.toString();
            return source.replace(this, value);
        }

        /**
         * Convert to RegExp object
         * @returns {RegExp} equivalent RegExp instance
         * @memberof VerbalExpression
         */

    }, {
        key: 'toRegExp',
        value: function toRegExp() {
            var components = this.toString().match(/\/(.*)\/([gimuy]+)?/);
            var pattern = components[1];
            var flags = components[2];

            return new RegExp(pattern, flags);
        }
    }], [{
        key: 'sanitize',
        value: function sanitize(value) {
            if (value instanceof RegExp) {
                return value.source;
            }

            if (typeof value === 'number') {
                return value;
            }

            if (typeof value !== 'string') {
                return '';
            }

            // Regular expression to match meta characters
            // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp
            var toEscape = /([\].|*?+(){}^$\\:=[])/g;

            // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch
            var lastMatch = '$&';

            // Escape meta characters
            return value.replace(toEscape, '\\' + lastMatch);
        }
    }]);

    return VerbalExpression;
}(_extendableBuiltin(RegExp));

/**
 * Return a new instance of `VerbalExpression`
 * @export
 * @returns {VerbalExpression} new instance
 */


function VerEx() {
    // eslint-disable-line no-unused-vars
    var instance = new VerbalExpression();
    instance.sanitize = VerbalExpression.sanitize;
    return instance;
}
//# sourceMappingURL=verbalexpressions.js.map

return VerEx;

}));


================================================
FILE: docs/404.md
================================================
# Page not found

Perhaps you wish to go to the [home page](/) instead?


================================================
FILE: docs/Gemfile
================================================
source "https://rubygems.org"

gem "github-pages", group: :jekyll_plugins



================================================
FILE: docs/VerEx.md
================================================
# `VerEx`

Return a new instance of [`VerbalExpression`](VerbalExpression).

This is the function that is exported from within `VerbalExpressions.js` and is to be the first method in chains that describe verbal expressions.


================================================
FILE: docs/VerbalExpression/capture-groups.md
================================================
# Capture Groups

Capture groups are used to extract data from within the regular expression match for further processing.

## `beginCapture`

Begin a capture group.

## `endCapture`

End a capture group.

___

```js
const phoneNumber = VerEx()
    .find('+')
    .beginCapture()
        .digit().repeatPrevious(2)
    .endCapture()
    .then('-')
    .digit().repeatPrevious(10);

const [, countryCode] = phoneNumber.exec('+91-2223387510');
console.log(countryCode); // => '91'
```


================================================
FILE: docs/VerbalExpression/constructor.md
================================================
# Constructor

## `constructor`

Construct and return a new instance of [`VerbalExpression`](#verbalexpression). Used to support the `new VerbalExpression()` syntax in ES6 classes as mandated by [the spec](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor). You usually wouldn't need to call `VerEx().constructor()`.


================================================
FILE: docs/VerbalExpression/index.md
================================================
---
title: VerbalExpression
---

# `VerbalExpression`

A class that extends [`RegExp`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) and wraps all VerbalExpressions functionality.

## Table of Contents

- [Constructor](../VerbalExpression/constructor)
    - [`constructor`](../VerbalExpression/constructor#constructor)
- [Utilities](../VerbalExpression/utilities)
    - [`static sanitize`](../VerbalExpression/utilities#static)
    - [`add`](../VerbalExpression/utilities#add)
- [Rules](../VerbalExpression/rules)
    - [`startOfLine`](../VerbalExpression/rules#startOfLine)
    - [`endOfLine`](../VerbalExpression/rules#endOfLine)
    - [`then`](../VerbalExpression/rules#then)
    - [`find`](../VerbalExpression/rules#find)
    - [`maybe`](../VerbalExpression/rules#maybe)
    - [`or`](../VerbalExpression/rules#or)
    - [`anything`](../VerbalExpression/rules#anything)
    - [`anythingBut`](../VerbalExpression/rules#anythingBut)
    - [`something`](../VerbalExpression/rules#something)
    - [`somethingBut`](../VerbalExpression/rules#somethingBut)
    - [`anyOf`](../VerbalExpression/rules#anyOf)
    - [`any`](../VerbalExpression/rules#any)
    - [`not`](../VerbalExpression/rules#not)
    - [`range`](../VerbalExpression/rules#range)
- [Special Characters](../VerbalExpression/special-characters)
    - [`lineBreak`](../VerbalExpression/special-characters#lineBreak)
    - [`br`](../VerbalExpression/special-characters#br)
    - [`tab`](../VerbalExpression/special-characters#tab)
    - [`word`](../VerbalExpression/special-characters#word)
    - [`digit`](../VerbalExpression/special-characters#digit)
    - [`whitespace`](../VerbalExpression/special-characters#whitespace)
- [Modifiers](../VerbalExpression/modifiers)
    - [`addModifier`](../VerbalExpression/modifiers#addModifier)
    - [`removeModifier`](../VerbalExpression/modifiers#removeModifier)
    - [`withAnyCase`](../VerbalExpression/modifiers#withAnyCase)
    - [`stopAtFirst`](../VerbalExpression/modifiers#stopAtFirst)
    - [`searchOneLine`](../VerbalExpression/modifiers#searchOneLine)
    - [`repeatPrevious`](../VerbalExpression/modifiers#repeatPrevious)
- [Loops](../VerbalExpression/loops)
    - [`oneOrMore`](../VerbalExpression/loops#oneOrMore)
    - [`multiple`](../VerbalExpression/loops#multiple)
- [Capture Groups](../VerbalExpression/capture-groups)
    - [`beginCapture`](../VerbalExpression/capture-groups#beginCapture)
    - [`endCapture`](../VerbalExpression/capture-groups#endCapture)
- [Miscellaneous](../VerbalExpression/miscellaneous)
    - [`replace`](../VerbalExpression/miscellaneous#replace)
    - [`toRegExp`](../VerbalExpression/miscellaneous#toRegExp)


================================================
FILE: docs/VerbalExpression/loops.md
================================================
# Loops

## `oneOrMore`

Match the previous stuff one or more times.

```js
const integer = VerEx().digit().oneOrMore();
console.log(integer.exec('foo 12345')[0]); // => '12345'
```

## `multiple`

### Usage 1

Match the previous group any number of times.

```js
const expr = VerEx().startOfLine().find(' ').multiple().endOfLine();

console.log(expr.test('   ')); // => true
```

### Usage 2

Match something zero or more times.

Parameter | Expected type | Description
----------|---------------|--------------
`value`   | `String`      | Item to match

```js
const expr = VerEx()
    .find('what').multiple('?')
    .endOfLine();

console.log(expr.test('what')); // => true
expr.lastIndex = 0;
console.log(expr.test('what???'));// => true
```

### Usage 3

Match something greater than or equal to `min` number of times.

Parameter | Expected type | Description
----------|---------------|---------------------------------------------
`value`   | `String`      | Item to match
`min`     | `Number`      | Minimum number of times it should be present

```js
const expr = VerEx()
    .find('hurray').then('!').multiple(1)
    .endOfLine();

console.log(expr.test('hurray')); // => false
expr.lastIndex = 0;
console.log(expr.test('hurray!!')); // => true
```

### Usage 4

Match something between `min` and `max` (inclusive) number of times.

Parameter | Expected type | Description
----------|---------------|---------------------------------------------
`value`   | `String`      | Item to match
`min`     | `Number`      | Minimum number of times it should be present
`max`     | `Number`      | Maximum number of times it should be present

```js
const expr = VerEx()
    .find('h').then('i').multiple(1, 3)
    .endOfLine();

console.log(expr.test('hiii')); // => true
expr.lastIndex = 0;
console.log(expr.test('hiiii')); // => false
```


================================================
FILE: docs/VerbalExpression/miscellaneous.md
================================================
# Miscellaneous

## `replace`

Replace characters matching the VerbalExpression in a string with another string.

Parameter | Expected type | Description
----------|---------------|-------------------------------
`source`  | `String`      | String to look for matches in
`value`   | `String`      | String to replace matches with

Return type: [`String`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)

```js
const spaces = VerEx().find(' ');
const fileName = 'a file name.txt';

// => 'a_file_name.txt'
console.log(spaces.replace(fileName, '_'));
```

## `toRegExp`

Convert the class to a [`RegExp`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) object.

Return type: [`RegExp`](//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)

```js
const expr = VerEx().find('foo');
console.log(expr.toRegExp()); // => /(?:foo)/gm
```


================================================
FILE: docs/VerbalExpression/modifiers.md
================================================
# Modifiers

## `addModifier`

Manually add a regex modifier (flag).

Parameter | Expected type | Description
----------|---------------|----------------
`value`   | `String`      | Modifier to add

```js
let expr = VerEx()
console.log(expr.flags); // => 'gm'

expr = expr.addModifier('i');
console.log(expr.flags); // => 'gim'
```

## `removeModifier`

Manually remove a regex modifier (flag).

Parameter | Expected type | Description
----------|---------------|-------------------
`value`   | `String`      | Modifier to remove

```js
let expr = VerEx();
console.log(expr.flags); // => 'gm'

expr = expr.removeModifier('m');
console.log(expr.flags); // => 'g'
```

## `withAnyCase`

Control case-insensitive matching. Equivalent to adding or removing the `i` modifier.

Parameter | Expected type | Description
----------|---------------|------------
`enable` (defaults to `true`) | `boolean` | Whether to enable this behavior

```js
const hexColorCode = VerEx()
    .find('#')
    .range('0', '9', 'a', 'f')
    .repeatPrevious(6)
    .withAnyCase();

console.log(hexColorCode.test('#93afee')); // => true
hexColorCode.lastIndex = 0;
console.log(hexColorCode.test('#93AFEE')); // => true
```

## `stopAtFirst`

Control global matching. Enabling would cause the expression to not look for matches beyond the first match. Equivalent to removing or adding the `g` modifier. Global matching is enabled by default.

Parameter | Expected type | Description
----------|---------------|------------
`enable` (defaults to `true`) | `boolean` | Whether to enable this behavior

```js
```

## `searchOneLine`

Control multi-line matching. Enabling would cause the expression to not look for matches beyond the first line. Equivalent to removing or adding the `m` modifier. Multi-line matching is enabled by default.

Parameter | Expected type | Description
----------|---------------|------------
`enable` (defaults to `true`) | `boolean` | Whether to enable this behavior

```js
let findFoo = VerEx().startOfLine().find('foo').endOfLine();
console.log(findFoo.test('foo\nfoo\nfoo')); // => true

findFoo = findFoo.searchOneLine();
console.log(findFoo.test('foo\nfoo\nfoo')); // => false
```

## `repeatPrevious`

### Usage 1

Repeat the previous item exactly `count` times.

Parameter | Expected type | Description
----------|---------------|------------
`count`   | `Number`      | Number of times to repeat the previous item

```js
const expr = VerEx()
    .startOfLine()
    .find('foo')
    .repeatPrevious(2)
    .endOfLine();

console.log(expr.test('foofoo')); // => true
expr.lastIndex = 0;
console.log(expr.test('foofoofoo')); // => false
```

### Usage 2

Repeat the previous item between `mix` and `max` (inclusive) times.

Parameter | Expected type | Description
----------|---------------|------------
`min`     | `Number`      | Minimum number of times to repeat the previous item
`max`     | `Number`      | Maximum number of times to repeat the previous item

```js
const expr = VerEx()
    .startOfLine()
    .find('foo')
    .repeatPrevious(1, 3)
    .endOfLine();

console.log(expr.test('foo')); // => true
expr.lastIndex = 0;
console.log(expr.test('foofoo')); // => true
expr.lastIndex = 0;
console.log(expr.test('foofoofoo')); // => true
expr.lastIndex = 0;
console.log(expr.test('foofoofoofoo')); // => false
```


================================================
FILE: docs/VerbalExpression/rules.md
================================================
# Rules

## `startOfLine`

Control whether to match the expression only if it appears from the beginning of the line.

Parameter | Expected type | Description
----------|---------------|------------
`enable` (defaults to `true`)  | `boolean` | Whether to enable this behavior

```js
const expr1 = VerEx().find('apple');
console.log(expr1.test('pineapple')); // => true

const expr2 = VerEx().startOfLine().find('apple');
console.log(expr2.test('pineapple')); // => false
```

## `endOfLine`

Control whether to match the expression only if it appears till the end of the line.

Parameter | Expected type | Description
----------|---------------|------------
`enable` (defaults to `true`)  | `boolean` | Whether to enable this behavior

```js
const expr1 = VerEx().find('apple');
console.log(expr1.test('apples')); // => true

const expr2 = VerEx().find('apple').endOfLine();
console.log(expr2.test('apples')); // => false
```

## `then`

Match an expression.

Parameter | Expected type | Description
----------|---------------|------------
`value`   | `String`, `number`, `RegExp`, `VerbalExpression` | Expression to match

```js
const expr = VerEx().then('foo');
console.log(expr.test('foo')); // => true
```

## `find`

Alias for [`then`](#then). Meant for semantics when used at the beginning of a verbal expression. For example, `VerEx().find('foo')` is more readable than `VerEx().then('foo')`.

## `maybe`

Optionally match an expression.

Parameter | Expected type | Description
----------|---------------|------------
`value`   | `String`, `number`, `RegExp`, `VerbalExpression` | Expression to optionally match

```js
const protocol = VerEx().find('http').maybe('s').then('://');

console.log(protocol.test('http://')); // => true
protocol.lastIndex = 0;
console.log(protocol.test('https://')); // => true
```

## `or`

Alternatively, match another expression.

Parameter | Expected type | Description
----------|---------------|------------
`value` (optional)  | `String`, `number`, `RegExp`, `VerbalExpression` | Expression to match instead

If no parameters are passed into `or`, the alternate expression would be the one built after the call to `or`.

```js
let fooOrBar = VerEx().find('foo').or('bar');
console.log(expr.test('foo')); // => true
fooOrBar.lastIndex = 0
console.log(expr.test('bar')); // => true

// alternate syntax
fooOrBar = VerEx().find('foo').or().find('bar');
console.log(expr.test('foo')); // => true
fooOrBar.lastIndex = 0
console.log(expr.test('bar')); // => true
```

## `anything`

Match any character(s) any (including zero) number of times.

```js
const anything = VerEx().anything();

console.log(anything.test('')); // => true
anything.lastIndex = 0;
console.log(anything.test('x')); // => true
```

## `anythingBut`

Match any character(s) except these any (including zero) number of times.

Parameter | Expected type        | Description
----------|----------------------|------------------------
`value`   | `String`, `[String]` | Characters to not match

```js
const anythingButXyz = VerEx().anythingBut('xyz');

console.log(anythingButXyz.test('')); // => true
anythingButXyz.lastIndex = 0;
console.log(anythingButXyz.test('a')); // => true
anythingButXyz.lastIndex = 0;
console.log(anythingButXyz.test('x')); // => false
```

## `something`

Match any character(s) at least once.

```js
const something = VerEx().something();

console.log(something.test('abc')); // => true
something.lastIndex = 0;
console.log(something.test('')); // => false
```

## `somethingBut`

Match any character(s) except these at least once.

Parameter | Expected type        | Description
----------|----------------------|------------------------
`value`   | `String`, `[String]` | Characters to not match

```js
const somethingButXyz = VerEx().somethingBut('xyz');

console.log(somethingButXyz.test('abc')); // => true
somethingButXyz.lastIndex = 0;
console.log(somethingButXyz.test('')); // => false
somethingButXyz.lastIndex = 0;
console.log(somethingButXyz.test('xyz')); // => false
```

## `anyOf`

Match any of these characters exactly once.

Parameter | Expected type         | Description
----------|-----------------------|--------------------
`value`   | `String`,  `[String]` | Characters to match

```js
const expr = VerEx().anyOf('abc');
console.log(expr.test('c')); // => true
expr.lastIndex = 0;
console.log(expr.test('d')); // => false
```

## `any`

Alias for [`anyOf`](#anyof).

## `not`

Ensure that the parameter does not follow.

Parameter | Expected type   | Description
----------|-----------------|---------------------------
`value`   | `String|Number` | Value to ensure absence of

```js
const notLeapDay = VerEx().startOfLine()not('FEB-29').something().endOfLine();

console.log(notLeapDay.test('FEB-29-2017')); // => false
notLeapDay.lastIndex = 0;
console.log(notLeapDay.test('FEB-28-2017')); // => true
```

## `range`

Match any character within the range defined by the parameters.

Parameter  | Expected type | Description
-----------|---------------|--------------------
`...range` | `String[]`    | Range of characters

Arguments will be interpreted as pairs.

For example, `.range('a', 'z', '0', '9')` will be interpreted to mean any character within the ranges `a–z` (ascii x–y) or `0–9` (ascii x–y). The method expects an even number of parameters; unpaired parameters are ignored.

```js
const hex = VerEx().range('0', '9', 'a', 'f').oneOrMore();

console.log(hex.test('b39a3f')); // => true
hex.lastIndex = 0;
console.log(hex.test('b39aeg')); // => false
```


================================================
FILE: docs/VerbalExpression/special-characters.md
================================================
# Special Characters

## `lineBreak`

Match a line break (both [Unix style](//codepoints.net/U+000A) and [Windows style](//codepoints.net/U+000D)).

```js
const expr = VerEx().find('foo').lineBreak().then('bar');
console.log(expr.test('foo\nbar'));
```

## `br`

An alias for [`lineBreak`](#linebreak).

## `tab`

Match a [tab character](//codepoints.net/U+0009).

```js
const tabs = VerEx().tab();
const code = '\tconsole.log("tabs vs spaces")';

// => '    console.log("tabs vs spaces")'
console.log(tabs.replace(code, '    '));
```

## `word`

Match a word—a string of word characters (a–z, A–Z, 0–9 or \_).

```js
const word = VerEx().startOfLine().word().endOfLine();

console.log(word.test('foo')); // => true
word.lastIndex = 0;
console.log(word.test('foo-bar')); // => false
```

## `digit`

Match a digit (0–9).

```js
const digit = VerEx().digit();
console.log(digit.test('2')); // => true
```

## `whitespace`

Match a whitespace character (one of [space](//codepoints.net/U+0020), [tab](//codepoints.net/U+0009), [carriage return](//codepoints.net/U+000D), [new line](//codepoints.net/U+000), [vertical tab](//codepoints.net/U+000B) and [form feed](//codepoints.net/U+000C)).

```js
const expr = VerEx().word().whitespace().word();
console.log(expr.test('word\tword')); // => true
```


================================================
FILE: docs/VerbalExpression/utilities.md
================================================
# Utilities

## `static sanitize`

Escape characters expected special by regex engines (all of `.`, `|`, `*`, `?`, `+`, `(`, `)`, `{`, `}`, `^`, `$`, `\`, `:`, `=`, `[` and `]`).

Parameter | Expected type | Description
----------|---------------|-------------------
`value`   | `String`      | String to sanitize

This method will not be accessible from outside the source file since `VerEx()` returns an instance of the class rather than the class itself.

```js
const stringToEscape = '(http://example.com?arg=foo+bar)';

// => '\(http:\/\/example.com\?arg\=foo\+bar\)'
console.log(VerbalExpression.sanitize(stringToEscape));
```

`sanitize` is a static method on the `VerbalExpression` class. However, it is also exposed as `VerEx().sanitize`.

## `add`

Append a literal expression to the object.

Parameter                   | Expected type | Description
----------------------------|---------------|--------------------------------
`value` (defaults to `''`)  | `String`      | Expression to add to the object

```js
const expr = VerEx();
expr.add('(foo)?(?:bar)*');

console.log(expr); // => /(foo)?(?:bar)*/gm
```


================================================
FILE: docs/_config.yml
================================================
title: JSVerbalExpressions Docs
description: API Documentation for JSVerbalExpressions.
repository: VerbalExpressions/JSVerbalExpressions

show_downloads: true

theme: jekyll-theme-minimal

exclude:
    - Gemfile
    - Gemfile.lock
    - .gitignore

cdn_url: https://jsdelivr.com/package/npm/verbal-expressions
npm_url: https://npmjs.com/package/verbal-expressions
minified_url: https://cdn.jsdelivr.net/npm/verbal-expressions@latest/dist/verbalexpressions.min.js



================================================
FILE: docs/_layouts/default.html
================================================
<!DOCTYPE html>
<html lang="{{ site.lang | default: "en-US" }}">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        {% seo %}

        <link rel="stylesheet" href="{{ "/assets/css/style.css" | relative_url }}">

        <!--[if lt IE 9]>
            <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
        <![endif]-->
    </head>
    <body>
        <div class="wrapper">
            <header>
                <h1><a href="{{ "/" | absolute_url }}">{{ site.title | default: site.github.repository_name }}</a></h1>

                <p>{{ site.description | default: site.github.project_tagline }}</p>

                {% if site.logo %}
                    <img src="{{ site.logo | relative_url }}" alt="Logo" />
                {% endif %}

                {% if site.github.is_project_page %}
                <p class="view"><a href="{{ site.github.repository_url }}">View the Project on GitHub <br> <small>{{ site.github.repository_nwo }}</small></a></p>
                {% endif %}

                {% if site.github.is_user_page %}
                <p class="view"><a href="{{ site.github.owner_url }}">View My GitHub Profile</a></p>
                {% endif %}

                <br>

                <a href="{{ "/VerEx" | absolute_url }}"><code>VerEx</code></a> • <a href="{{ "/VerbalExpression" | absolute_url }}"><code>VerbalExpression</code></a>

                <br> <br> <br>

                <ul>
                    <li><a href="{{ site.minified_url }}">Download <strong>Minified</strong></a></li>
                    <li><a href="{{ site.cdn_url }}">Use via <strong>JSDelivr</strong></a></li>
                    <li><a href="{{ site.npm_url }}">View on <strong>NPM</strong></a></li>
                </ul>
            </header>

            <section> {{ content }} </section>
        </div>
        <script src="{{ "/assets/js/scale.fix.js" | relative_url }}"></script>
    </body>
</html>


================================================
FILE: docs/assets/css/style.scss
================================================
---
---

@import "{{ site.theme }}";

.wrapper {
    width: 900px;
}

section {
    width: 540px;
}

ul {
    margin-bottom: 5px;
    list-style: none;
    padding-left: 2em;
}

hr {
    margin: 20px 0;
}

a:hover {
    font-weight: inherit;
}

a code {
    color: #267CB9;
}

a code:hover {
    color: #006699;
}

details {
    padding-bottom: 20px;
}


================================================
FILE: docs/index.md
================================================
---
title: Home
---

VerbalExpressions is a JavaScript library that helps to construct difficult regular expressions. For more details, refer to the [README](//github.com/VerbalExpressions/JSVerbalExpressions#readme).

# Table Of Contents

- [`VerEx`](VerEx)
- [`VerbalExpression`](VerbalExpression)
    - [Constructor](VerbalExpression/constructor)
    - [Utilities](VerbalExpression/utilities)
    - [Rules](VerbalExpression/rules)
    - [Special Characters](VerbalExpression/special-characters)
    - [Modifiers](VerbalExpression/modifiers)
    - [Loops](VerbalExpression/loops)
    - [Capture Groups](VerbalExpression/capture-groups)
    - [Miscellaneous](VerbalExpression/miscellaneous)

___

Methods have a return type of [`VerbalExpression`](VerbalExpressions) except where mentioned otherwise. If there is no mention of a method's parameters, it is to be assumed that it has none.


================================================
FILE: package.json
================================================
{
  "name": "verbal-expressions",
  "description": "JavaScript Regular expressions made easy",
  "version": "1.0.2",
  "keywords": [
    "regular expressions",
    "regex"
  ],
  "homepage": "https://github.com/VerbalExpressions/JSVerbalExpressions",
  "devDependencies": {
    "@babel/preset-env": "^7.12.1",
    "ava": "^3.13.0",
    "babel-core": "^6.26.3",
    "babel-plugin-transform-builtin-extend": "^1.1.2",
    "eslint": "^8.10.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.21.5",
    "grunt": "^1.3.0",
    "grunt-ava": "^0.19.0",
    "grunt-babel": "^8.0.0",
    "grunt-contrib-uglify": "^5.0.0",
    "grunt-eslint": "^24.0.0",
    "grunt-markdownlint": "^3.1.0",
    "grunt-sourcemap-localize": "^0.1.0",
    "grunt-umd": "^3.0.0",
    "nyc": "^15.1.0"
  },
  "repository": {
    "type": "git",
    "url": "git://github.com/VerbalExpressions/JSVerbalExpressions.git"
  },
  "bugs": {
    "url": "https://github.com/VerbalExpressions/JSVerbalExpressions/issues"
  },
  "main": "dist/verbalexpressions.js",
  "license": "MIT",
  "scripts": {
    "test": "grunt test",
    "test:verbose": "grunt test:verbose",
    "compile": "grunt compile",
    "grunt": "grunt",
    "build": "grunt build"
  },
  "types": "./typings/VerbalExpressions.d.ts",
  "engines": {
    "node": ">=9.2.0"
  },
  "dependencies": {},
  "prettier": {
    "singleQuote": true
  }
}


================================================
FILE: test/tests.js
================================================
const test = require('ava');
const VerEx = require('../dist/verbalexpressions');

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test#Using_test()_on_a_regex_with_the_global_flag
function resetLastIndex(regex) {
    regex.lastIndex = 0;
}

test('constructor', (t) => {
    const testRegex = VerEx();

    t.true(testRegex instanceof RegExp, 'Should extend RegExp');
    t.is(testRegex.toString(), '/(?:)/gm', 'Should be empty regex with global, multiline matching');
});

// Utility //

test('sanitize', (t) => {
    const testString = '$a^b\\c|d(e)f[g]h{i}j.k*l+m?n:o=p';
    const escaped = '\\$a\\^b\\\\c\\|d\\(e\\)f\\[g\\]h\\{i\\}j\\.k\\*l\\+m\\?n\\:o\\=p';

    t.is(VerEx().sanitize(testString), escaped, 'Special characters should be sanitized');

    t.is(VerEx().sanitize(42), 42);
    t.is(VerEx().sanitize(/foo/), 'foo');

    t.notThrows(() => VerEx().sanitize());
    t.notThrows(() => VerEx().sanitize(NaN));
    t.notThrows(() => VerEx().sanitize(null));
    t.notThrows(() => VerEx().sanitize(true));
});

test('add', (t) => {
    let testRegex = VerEx().startOfLine().withAnyCase().endOfLine();
    testRegex = testRegex.add('(?:foo)?');

    t.true(testRegex.source.startsWith('^'), 'Should retain old prefixes');
    t.true(testRegex.source.endsWith('$'), 'Should retain old suffixes');

    t.true(testRegex.test('foo'), 'Should add new rules');
    resetLastIndex(testRegex);
    t.true(testRegex.test(''), 'Should add new rules');

    t.true(testRegex.flags.includes('i'), 'Should retain old modifiers');
});

// Rules //

test('startOfLine', (t) => {
    let testRegex = VerEx().startOfLine().then('a');
    let testString = 'a';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'ba';
    t.false(testRegex.test(testString));

    testRegex = testRegex.startOfLine(false); // start of line is no longer necessary
    testString = 'ba';
    t.true(testRegex.test(testString));
});

test('endOfLine', (t) => {
    let testRegex = VerEx().find('a').endOfLine();
    let testString = 'a';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'ab';
    t.false(testRegex.test(testString));

    testRegex = testRegex.endOfLine(false); // end of line is no longer necessary
    testString = 'ab';
    t.true(testRegex.test(testString));
});

function then(name, t) {
    let testRegex = VerEx()[name]('a');
    let testString = 'a';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'b';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = '';
    t.false(testRegex.test(testString));

    testRegex = VerEx()[name]('a')[name]('b');
    testString = 'ab';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'ac';
    t.false(testRegex.test(testString));
}

test('then', (t) => {
    then('then', t);
});

test('find', (t) => {
    then('find', t);
});

test('maybe', (t) => {
    const testRegex = VerEx().startOfLine().then('a').maybe('b');
    let testString = 'acb';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abc';
    t.true(testRegex.test(testString));
});

test('or', (t) => {
    let testRegex = VerEx().startOfLine().then('abc').or('def');
    let testString = 'defzzz';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abczzz';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'xyzabc';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('abc').or().then('def');
    testString = 'defzzz';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abczzz';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'xyzabc';
    t.false(testRegex.test(testString));
});

test('anything', (t) => {
    const testRegex = VerEx().startOfLine().anything();
    let testString = 'foo';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = '';
    t.true(testRegex.test(testString), 'Should be able to match zero characters');
});

test('anythingBut', (t) => {
    let testRegex = VerEx().startOfLine().anythingBut('br').endOfLine();
    let testString = 'foobar';

    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foo_a_';
    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().anythingBut('br');
    testString = 'bar';
    t.true(testRegex.test(testString), 'Should be able to match zero characters');

    testRegex = VerEx().startOfLine().anythingBut(['b', 'r']).endOfLine();
    testString = 'foobar';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foo_a_';
    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().anythingBut(['b', 'r']);
    testString = 'bar';
    t.true(testRegex.test(testString), 'Should be able to match zero characters');
});

test('something', (t) => {
    const testRegex = VerEx().something();
    let testString = '';

    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'a';
    t.true(testRegex.test(testString));
});

test('somethingBut', (t) => {
    let testRegex = VerEx().startOfLine().somethingBut('abc').endOfLine();
    let testString = '';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foo';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'fab';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().somethingBut(['a', 'b', 'c']).endOfLine();
    testString = '';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foo';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'fab';
    t.false(testRegex.test(testString));
});

function anyOf(name, t) {
    let testRegex = VerEx().startOfLine().then('a')[name]('xyz');
    let testString = 'ay';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'ab';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'a';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('a')[name](['x', 'y', 'z']);
    testString = 'ay';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'ab';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'a';
    t.false(testRegex.test(testString));
}

test('anyOf', (t) => {
    anyOf('anyOf', t);
});

test('any', (t) => {
    anyOf('any', t);
});

test('not', (t) => {
    const testRegex = VerEx().startOfLine().not('foo').anything().endOfLine();
    let testString = 'foobar';

    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'bar';
    t.true(testRegex.test(testString));
});

test('range', (t) => {
    let testRegex = VerEx().startOfLine().range('a', 'z', '0', '9').oneOrMore().endOfLine();
    let testString = 'foobarbaz123';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'fooBarBaz_123';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().range('a', 'z', '0').oneOrMore().endOfLine();
    testString = 'foobarbaz';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foobarbaz123';
    t.false(testRegex.test(testString), 'Should ignore extra parameters');
});

// Special characters //

function lineBreak(name, t) {
    const testRegex = VerEx().startOfLine().then('abc')[name]().then('def');
    let testString = 'abc\r\ndef';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abc\ndef';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abc\rdef';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abc\r\n\ndef';
    t.false(testRegex.test(testString));
}

test('lineBreak', (t) => {
    lineBreak('lineBreak', t);
});

test('br', (t) => {
    lineBreak('br', t);
});

test('tab', (t) => {
    const testRegex = VerEx().startOfLine().tab().then('abc');
    let testString = '\tabc';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'abc';
    t.false(testRegex.test(testString));
});

test('word', (t) => {
    let testRegex = VerEx().startOfLine().word().endOfLine();
    let testString = 'azertyuiopqsdfghjklmwxcvbn0123456789_';

    t.true(testRegex.test(testString));

    testRegex = VerEx().word();
    testString = '. @[]|,&~-';
    t.false(testRegex.test(testString));
});

test('digit', (t) => {
    let testRegex = VerEx().startOfLine().digit().oneOrMore().endOfLine();
    let testString = '0123456789';

    t.true(testRegex.test(testString));

    testRegex = VerEx().digit();
    testString = '-.azertyuiopqsdfghjklmwxcvbn @[]|,_&~';
    t.false(testRegex.test(testString));
});

test('whitespace', (t) => {
    const testRegex = VerEx().startOfLine().whitespace().oneOrMore().searchOneLine().endOfLine();
    let testString = ' \t\r\n\v\f';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'a z';
    t.false(testRegex.test(testString));
});

// Modifiers //

test('addModifier', (t) => {
    let testRegex = VerEx().addModifier('y');
    t.true(testRegex.flags.includes('y'));

    t.notThrows(() => {
        testRegex = VerEx().addModifier('g');
    }, 'Should not add extra modifier if it already exists');
});

test('removeModifier', (t) => {
    const testRegex = VerEx().removeModifier('g');
    t.false(testRegex.flags.includes('g'));
});

test('withAnyCase', (t) => {
    let testRegex = VerEx().startOfLine().then('a');
    let testString = 'A';

    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('a').withAnyCase();
    testString = 'A';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'a';
    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('a').withAnyCase(false);
    testString = 'A';
    t.false(testRegex.test(testString));
});

test('stopAtFirst', (t) => {
    let testRegex = VerEx().find('foo');
    const testString = 'foofoofoo';

    t.is(testString.match(testRegex).length, 3, 'Should match all "foo"s');

    testRegex = VerEx().find('foo').stopAtFirst();
    t.is(testString.match(testRegex).length, 1, 'Should match one "foo"');

    testRegex = VerEx().find('foo').stopAtFirst(false);
    t.is(testString.match(testRegex).length, 3, 'Should match all "foo"s');
});

test('searchOneLine', (t) => {
    let testRegex = VerEx().startOfLine().then('b').endOfLine();
    const testString = 'a\nb\nc';

    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('b').endOfLine().searchOneLine();
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().then('b').endOfLine().searchOneLine(false);
    t.true(testRegex.test(testString));
});

// Loops //

test('repeatPrevious', (t) => {
    let testRegex = VerEx().startOfLine().find('foo').repeatPrevious(3).endOfLine();
    let testString = 'foofoofoo';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoo';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoofoofoo';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'bar';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().find('foo').repeatPrevious(1, 3).endOfLine();

    for (let i = 0; i <= 4; i++) {
        resetLastIndex(testRegex);
        testString = 'foo'.repeat(i);

        if (i < 1 || i > 3) {
            t.false(testRegex.test(testString));
        } else {
            t.true(testRegex.test(testString));
        }
    }

    testRegex = VerEx().startOfLine().find('foo').repeatPrevious().endOfLine();
    testString = 'foofoo';
    t.false(testRegex.test(testString), 'Should silently fail on edge cases');

    testRegex = VerEx().startOfLine().find('foo').repeatPrevious(1, 2, 3).endOfLine();
    testString = 'foofoo';
    t.false(testRegex.test(testString), 'Should silently fail on edge cases');
});

test('oneOrMore', (t) => {
    const testRegex = VerEx().startOfLine().then('foo').oneOrMore().endOfLine();
    let testString = 'foo';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoo';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'bar';
    t.false(testRegex.test(testString));
});

test('multiple', (t) => {
    let testRegex = VerEx().startOfLine().find(' ').multiple().endOfLine();
    let testString = '   ';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = ' a ';
    t.false(testRegex.test(testString));

    testRegex = VerEx().startOfLine().multiple('foo').endOfLine();
    testString = 'foo';

    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoofoo';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = '';
    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().multiple('foo', 2).endOfLine();
    testString = 'foo';
    t.false(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoo';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    testString = 'foofoofoo';
    t.true(testRegex.test(testString));

    testRegex = VerEx().startOfLine().multiple('foo', 2, 5).endOfLine();

    for (let i = 0; i <= 6; i++) {
        resetLastIndex(testRegex);
        testString = 'foo'.repeat(i);

        if (i < 2 || i > 5) {
            t.false(testRegex.test(testString));
        } else {
            t.true(testRegex.test(testString));
        }
    }
});

// Capture groups //

test('capture groups', (t) => {
    let testRegex = VerEx().find('foo').beginCapture().then('bar');
    let testString = 'foobar';

    t.true(testRegex.test(testString), 'Expressions with incomplete capture groups should work');

    testRegex = testRegex.endCapture().then('baz');
    testString = 'foobarbaz';
    t.true(testRegex.test(testString));

    resetLastIndex(testRegex);
    const matches = testRegex.exec(testString);
    t.is(matches[1], 'bar');
});

// Miscellaneous //

test('replace', (t) => {
    const testRegex = VerEx().find(' ');
    const testString = 'foo bar baz';

    t.is(testRegex.replace(testString, '_'), 'foo_bar_baz');
});

test('toRegExp', (t) => {
    const testRegex = VerEx().anything();
    const converted = testRegex.toRegExp();

    t.is(converted.toString(), testRegex.toString(), 'Converted regex should have same behaviour');
});


================================================
FILE: typings/VerbalExpressions.d.ts
================================================
// Type definitions for JSVerbalExpressions
// Project: https://github.com/VerbalExpressions/JSVerbalExpressions
// Definitions by: Mihai Ionut Vilcu <https://github.com/ionutvmi>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

type RegExpFlags = "g" | "i" | "m" | "u" | "y";
type Appendable = VerbalExpression | RegExp | string | number;

interface VerbalExpression extends RegExp {
    // Utility //
    /** Sanitation function for adding anything safely to the expression */
    sanitize(value: Appendable): VerbalExpression;
    /** Append literal expression to the object. Also refreshes the expression. */
    add(value: string | number): VerbalExpression;

    // Rules //
    /** Mark the expression to end at the last character of the line. */
    startOfLine(enable?: boolean): VerbalExpression;
    /** Mark the expression to start at the beginning of the line. */
    endOfLine(enable?: boolean): VerbalExpression;
    /** Add a string to the expression */
    then(value: Appendable): VerbalExpression;
    /** Add a string to the expression. Alias for then() */
    find(value: Appendable): VerbalExpression;
    /** Add a string to the expression that might appear once (or not). */
    maybe(value: Appendable): VerbalExpression;
    /** Add a alternative expression to be matched. */
    or(value?: Appendable): VerbalExpression;
    /** Match any character(s) any (including zero) number of times. */
    anything(): VerbalExpression;
    anythingBut(value: Appendable | string[]): VerbalExpression;
    /** Match any character(s) at least once. */
    something(): VerbalExpression;
    somethingBut(value: Appendable | string[]): VerbalExpression;
    /** Match any of the provided values */
    anyOf(value: Appendable | string[]): VerbalExpression;
    /** Match any of the provided values. Alias for anyOf() */
    any(value: Appendable | string[]): VerbalExpression;
    /** Ensure that the parameter does not follow. */
    not(value: Appendable): VerbalExpression;
    /** Add expression to match a range (or multiply ranges) */
    range(...values: string[]): VerbalExpression;

    // Special Characters
    /** Add universal line break expression */
    lineBreak(): VerbalExpression;
    /** Add universal line break expression. Alias for lineBreak() */
    br(): VerbalExpression;
    /** Add expression to match a tab character */
    tab(): VerbalExpression;
    /** Add expression to match a word */
    word(): VerbalExpression;
    /** Add expression to match a digit */
    digit(): VerbalExpression;
    /** Add expression to match a whitespace character */
    whitespace(): VerbalExpression;

    // Modifiers //
    /** Adds a modifier to the expression. */
    addModifier(modifier: RegExpFlags): VerbalExpression;
    /** Removes a modifier to the expression. */
    removeModifier(modifier: RegExpFlags): VerbalExpression;
    /** Makes the expression case insensitive */
    withAnyCase(enable?: boolean): VerbalExpression;
    /** Removes the 'g' modifier. */
    stopAtFirst(enable?: boolean): VerbalExpression;
    /** Removes the 'm' modifier. */
    searchOneLine(enable?: boolean): VerbalExpression;

    // Loops //
    /** Repeat the previous item between mix and max (inclusive) times. */
    repeatPrevious(min: number, max: number): VerbalExpression;
    /** Repeat the previous item exactly count times. */
    repeatPrevious(count: number): VerbalExpression;
    /** Match the previous stuff one or more times. */
    oneOrMore(): VerbalExpression;
    /** Match something greater than or equal to min number of times. Or of upper is set. Match something between min and max (inclusive) number of times. */
    multiple(value: string, lower: number, upper?: number): VerbalExpression;
    /** Match something zero or more times. */
    multiple(value: string): VerbalExpression;
    /** Match the previous group any number of times. */
    multiple(): VerbalExpression;
    /** Starts a capturing group */
    beginCapture(): VerbalExpression;
    /** Emds a capturing group */
    endCapture(): VerbalExpression;

    // Miscellaneous
    replace(source: string, value: string): string;
    /** Converts the verbal expression to a RegExp object */
    toRegExp(): RegExp;
}

interface VerbalExpressionConstructor {
    new(): VerbalExpression;
    (): VerbalExpression;
    prototype: VerbalExpression;
}

declare var VerEx: VerbalExpressionConstructor;
export = VerEx;
Download .txt
gitextract_ziqoi740/

├── .editorconfig
├── .eslintrc
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       ├── automerge.yml
│       ├── codeql-analysis.yml
│       ├── gh-pages.yml
│       └── test.yml
├── .gitignore
├── .mdlintrc.json
├── Gruntfile.js
├── LICENSE
├── README.md
├── VerbalExpressions.js
├── bower.json
├── dist/
│   └── verbalexpressions.js
├── docs/
│   ├── 404.md
│   ├── Gemfile
│   ├── VerEx.md
│   ├── VerbalExpression/
│   │   ├── capture-groups.md
│   │   ├── constructor.md
│   │   ├── index.md
│   │   ├── loops.md
│   │   ├── miscellaneous.md
│   │   ├── modifiers.md
│   │   ├── rules.md
│   │   ├── special-characters.md
│   │   └── utilities.md
│   ├── _config.yml
│   ├── _layouts/
│   │   └── default.html
│   ├── assets/
│   │   └── css/
│   │       └── style.scss
│   └── index.md
├── package.json
├── test/
│   └── tests.js
└── typings/
    └── VerbalExpressions.d.ts
Download .txt
SYMBOL INDEX (52 symbols across 4 files)

FILE: VerbalExpressions.js
  class VerbalExpression (line 15) | class VerbalExpression extends RegExp {
    method constructor (line 22) | constructor() {
    method sanitize (line 42) | static sanitize(value) {
    method add (line 72) | add(value = '') {
    method startOfLine (line 89) | startOfLine(enable = true) {
    method endOfLine (line 100) | endOfLine(enable = true) {
    method then (line 111) | then(value) {
    method find (line 122) | find(value) {
    method maybe (line 132) | maybe(value) {
    method or (line 143) | or(value) {
    method anything (line 161) | anything() {
    method anythingBut (line 171) | anythingBut(value) {
    method something (line 185) | something() {
    method somethingBut (line 195) | somethingBut(value) {
    method anyOf (line 210) | anyOf(value) {
    method any (line 225) | any(value) {
    method not (line 235) | not(value) {
    method range (line 249) | range(...ranges) {
    method lineBreak (line 269) | lineBreak() {
    method br (line 278) | br() {
    method tab (line 287) | tab() {
    method word (line 296) | word() {
    method digit (line 305) | digit() {
    method whitespace (line 314) | whitespace() {
    method addModifier (line 326) | addModifier(modifier) {
    method removeModifier (line 340) | removeModifier(modifier) {
    method withAnyCase (line 351) | withAnyCase(enable = true) {
    method stopAtFirst (line 361) | stopAtFirst(enable = true) {
    method searchOneLine (line 371) | searchOneLine(enable = true) {
    method repeatPrevious (line 382) | repeatPrevious(...quantity) {
    method oneOrMore (line 400) | oneOrMore() {
    method multiple (line 412) | multiple(value, lower, upper) {
    method beginCapture (line 436) | beginCapture() {
    method endCapture (line 447) | endCapture() {
    method replace (line 462) | replace(source, value) {
    method toRegExp (line 472) | toRegExp() {
  function VerEx (line 486) | function VerEx() { // eslint-disable-line no-unused-vars

FILE: dist/verbalexpressions.js
  function defineProperties (line 18) | function defineProperties(target, props) { for (var i = 0; i < props.len...
  function _classCallCheck (line 20) | function _classCallCheck(instance, Constructor) { if (!(instance instanc...
  function _possibleConstructorReturn (line 22) | function _possibleConstructorReturn(self, call) { if (!self) { throw new...
  function _inherits (line 24) | function _inherits(subClass, superClass) { if (typeof superClass !== "fu...
  function _extendableBuiltin (line 26) | function _extendableBuiltin(cls) {
  function VerbalExpression (line 74) | function VerbalExpression() {
  function VerEx (line 669) | function VerEx() {

FILE: test/tests.js
  function resetLastIndex (line 5) | function resetLastIndex(regex) {
  function then (line 79) | function then(name, t) {
  function anyOf (line 223) | function anyOf(name, t) {
  function lineBreak (line 291) | function lineBreak(name, t) {

FILE: typings/VerbalExpressions.d.ts
  type RegExpFlags (line 6) | type RegExpFlags = "g" | "i" | "m" | "u" | "y";
  type Appendable (line 7) | type Appendable = VerbalExpression | RegExp | string | number;
  type VerbalExpression (line 9) | interface VerbalExpression extends RegExp {
  type VerbalExpressionConstructor (line 94) | interface VerbalExpressionConstructor {
Condensed preview — 34 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (102K chars).
[
  {
    "path": ".editorconfig",
    "chars": 227,
    "preview": "root = true\n\n[*]\n    end_of_line = lf\n    trim_trailing_whitespace = true\n    insert_final_newline = true\n    indent_sty"
  },
  {
    "path": ".eslintrc",
    "chars": 655,
    "preview": "{\n    \"extends\": \"airbnb\",\n    \"rules\": {\n        \"indent\": [2, 4],\n        \"no-underscore-dangle\": [2, { \"allowAfterThi"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 268,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: npm\n    directory: \"/\"\n    schedule:\n      interval: daily\n    open-pull-requ"
  },
  {
    "path": ".github/workflows/automerge.yml",
    "chars": 1369,
    "preview": "name: Dependabot auto-merge\non: pull_request\n\npermissions:\n  pull-requests: write\n  contents: write\n\njobs:\n  dependabot:"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 2641,
    "preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
  },
  {
    "path": ".github/workflows/gh-pages.yml",
    "chars": 581,
    "preview": "name: Build docs/ folder\non: pull_request\njobs:\n    test:\n        name: Build docs/ folder\n        runs-on: ubuntu-lates"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 483,
    "preview": "name: Run tests\non: pull_request\njobs:\n    test:\n        name: Run tests on Node.js ${{ matrix.node-version }}\n        r"
  },
  {
    "path": ".gitignore",
    "chars": 101,
    "preview": "node_modules\n.DS_Store\n.idea/\n.vscode/\n.nyc_output\ndocs/_site\ndocs/.sass-cache\ndocs/.jekyll-metadata\n"
  },
  {
    "path": ".mdlintrc.json",
    "chars": 1220,
    "preview": "{\n    \"heading-increment\": true,\n    \"first-heading-h1\": { \"level\": 1 },\n    \"heading-style\": { \"style\": \"atx\" },\n    \"u"
  },
  {
    "path": "Gruntfile.js",
    "chars": 3107,
    "preview": "module.exports = function gruntConfig(grunt) {\n    grunt.initConfig({\n        pkg: grunt.file.readJSON('package.json'),\n"
  },
  {
    "path": "LICENSE",
    "chars": 1072,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017 jehna\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README.md",
    "chars": 6009,
    "preview": "# VerbalExpressions\n\n[![Build Status](https://travis-ci.org/VerbalExpressions/JSVerbalExpressions.svg)](https://travis-c"
  },
  {
    "path": "VerbalExpressions.js",
    "chars": 14126,
    "preview": "/**\n * @file VerbalExpressions JavaScript Library\n * @version 0.3.0\n * @license MIT\n *\n * @see https://github.com/Verbal"
  },
  {
    "path": "bower.json",
    "chars": 409,
    "preview": "{\n    \"name\": \"verbal-expressions\",\n    \"description\": \"JavaScript Regular expressions made easy\",\n    \"keywords\": [ \"re"
  },
  {
    "path": "dist/verbalexpressions.js",
    "chars": 21348,
    "preview": "(function (root, factory) {\n  if (root === undefined && window !== undefined) root = window;\n  if (typeof define === 'fu"
  },
  {
    "path": "docs/404.md",
    "chars": 72,
    "preview": "# Page not found\n\nPerhaps you wish to go to the [home page](/) instead?\n"
  },
  {
    "path": "docs/Gemfile",
    "chars": 75,
    "preview": "source \"https://rubygems.org\"\n\ngem \"github-pages\", group: :jekyll_plugins\n\n"
  },
  {
    "path": "docs/VerEx.md",
    "chars": 224,
    "preview": "# `VerEx`\n\nReturn a new instance of [`VerbalExpression`](VerbalExpression).\n\nThis is the function that is exported from "
  },
  {
    "path": "docs/VerbalExpression/capture-groups.md",
    "chars": 483,
    "preview": "# Capture Groups\n\nCapture groups are used to extract data from within the regular expression match for further processin"
  },
  {
    "path": "docs/VerbalExpression/constructor.md",
    "chars": 353,
    "preview": "# Constructor\n\n## `constructor`\n\nConstruct and return a new instance of [`VerbalExpression`](#verbalexpression). Used to"
  },
  {
    "path": "docs/VerbalExpression/index.md",
    "chars": 2692,
    "preview": "---\ntitle: VerbalExpression\n---\n\n# `VerbalExpression`\n\nA class that extends [`RegExp`](//developer.mozilla.org/en-US/doc"
  },
  {
    "path": "docs/VerbalExpression/loops.md",
    "chars": 1843,
    "preview": "# Loops\n\n## `oneOrMore`\n\nMatch the previous stuff one or more times.\n\n```js\nconst integer = VerEx().digit().oneOrMore();"
  },
  {
    "path": "docs/VerbalExpression/miscellaneous.md",
    "chars": 930,
    "preview": "# Miscellaneous\n\n## `replace`\n\nReplace characters matching the VerbalExpression in a string with another string.\n\nParame"
  },
  {
    "path": "docs/VerbalExpression/modifiers.md",
    "chars": 3326,
    "preview": "# Modifiers\n\n## `addModifier`\n\nManually add a regex modifier (flag).\n\nParameter | Expected type | Description\n----------"
  },
  {
    "path": "docs/VerbalExpression/rules.md",
    "chars": 5527,
    "preview": "# Rules\n\n## `startOfLine`\n\nControl whether to match the expression only if it appears from the beginning of the line.\n\nP"
  },
  {
    "path": "docs/VerbalExpression/special-characters.md",
    "chars": 1297,
    "preview": "# Special Characters\n\n## `lineBreak`\n\nMatch a line break (both [Unix style](//codepoints.net/U+000A) and [Windows style]"
  },
  {
    "path": "docs/VerbalExpression/utilities.md",
    "chars": 1123,
    "preview": "# Utilities\n\n## `static sanitize`\n\nEscape characters expected special by regex engines (all of `.`, `|`, `*`, `?`, `+`, "
  },
  {
    "path": "docs/_config.yml",
    "chars": 465,
    "preview": "title: JSVerbalExpressions Docs\ndescription: API Documentation for JSVerbalExpressions.\nrepository: VerbalExpressions/JS"
  },
  {
    "path": "docs/_layouts/default.html",
    "chars": 2083,
    "preview": "<!DOCTYPE html>\n<html lang=\"{{ site.lang | default: \"en-US\" }}\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta"
  },
  {
    "path": "docs/assets/css/style.scss",
    "chars": 353,
    "preview": "---\n---\n\n@import \"{{ site.theme }}\";\n\n.wrapper {\n    width: 900px;\n}\n\nsection {\n    width: 540px;\n}\n\nul {\n    margin-bot"
  },
  {
    "path": "docs/index.md",
    "chars": 889,
    "preview": "---\ntitle: Home\n---\n\nVerbalExpressions is a JavaScript library that helps to construct difficult regular expressions. Fo"
  },
  {
    "path": "package.json",
    "chars": 1470,
    "preview": "{\n  \"name\": \"verbal-expressions\",\n  \"description\": \"JavaScript Regular expressions made easy\",\n  \"version\": \"1.0.2\",\n  \""
  },
  {
    "path": "test/tests.js",
    "chars": 15098,
    "preview": "const test = require('ava');\nconst VerEx = require('../dist/verbalexpressions');\n\n// https://developer.mozilla.org/en-US"
  },
  {
    "path": "typings/VerbalExpressions.d.ts",
    "chars": 4449,
    "preview": "// Type definitions for JSVerbalExpressions\n// Project: https://github.com/VerbalExpressions/JSVerbalExpressions\n// Defi"
  }
]

About this extraction

This page contains the full source code of the VerbalExpressions/JSVerbalExpressions GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 34 files (94.1 KB), approximately 24.4k tokens, and a symbol index with 52 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!