Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/yyytcool/rexx

🦖 A human-friendly regex library with structured syntax and variable support.
https://github.com/yyytcool/rexx

regex regexp regular-expressions

Last synced: about 2 months ago
JSON representation

🦖 A human-friendly regex library with structured syntax and variable support.

Awesome Lists containing this project

README

        

🦖 Rexx


npm version
npm downloads
package.json version
codecov
Standard - JavaScript Style Guide
github actions
License


🎮  Playground
    
💻  Live Demo

> Rexx: A human-friendly regex library with structured syntax and variable support.

## Introduction

- Human readable.
- Structured syntax.
- Support for variables and comments.
- Easily build regular expression patterns.

## Installation

```sh
# Install rexx using npm
npm install rexx

# using Yarn
yarn add rexx

# using pnpm
pnpm install rexx
```

## Usage

### Browser

```html

```

### Node.js

```js
// CommonJS
const rexx = require('rexx')
// or ES6 Modules
import rexx from 'rexx'
```

## Examples
## Semantic Versioning
Semantic Versioning (SemVer) follows the pattern major.minor.patch, where major, minor, and patch are non-negative integers.
```js
const regExp = rexx(`
digits = { one_or_more { digit } }

semVer = {
begin
optional {'v'}
group('major') { digits }
'.'
group('minor') { digits }
'.'
group('patch') { digits }
end
}
`)
console.log(regExp)
// {
// digits: /\d+/,
// semVer: /^v?(?\d+)\.(?\d+)\.(?\d+)$/,
// default: /(?:)/,
// }
regExp.semVer.test('v1.2.3') // true
```

### URL
A URL contains several components - the protocol, host, path, query, and hash.

`http://www.example.com/foo/bar.html?a=b&c=d#hash`

```js
const urlRegexp = rexx(`
protocol = { optional { one_of{'http', 'https'} } } // http
host = { one_or_more { except{'/'} } } // www.example.com
path = { loop(0..) {'/', one_or_more { except{'/?#'} } } } // /foo/bar.html
query = { optional {'?', one_or_more { except{'#'} } } } // ?a=b&c=d
hash = { optional {'#', one_or_more { any } } } // #hash
url = {
group('protocol'){ protocol }
optional{'://'}
group('host'){ host }
group('path'){ path }
group('query'){ query }
group('hash'){ hash }
}
`)
console.log(urlRegexp.url)
// /(?(?:(?:http|https))?)(?:\:\/\/)?(?(?:[^\/])+)(?(?:\/(?:[^\/\?#])+)*)(?(?:\?(?:[^#])+)?)(?(?:#.+)?)/
urlRegexp.url.test('http://www.example.com/foo/bar.html?a=b&c=d#hash') // true
```
### Password validation
The password must contain characters from at least 3 of the following 4 rules:
upper case, lower case, numbers, non-alphanumeric.

```js
const pwdRegexp = rexx(`
lower = { one_of {range {'a', 'z'} } }
upper = { one_of {range {'A', 'Z'} } }
_any = { loop(0..) { any } }
hasLower = { followed_by { _any, lower } }
hasUpper = { followed_by { _any, upper } }
hasDigit = { followed_by { _any, digit } }
hasSymbol = { followed_by { _any, non_word } }
password = {
begin
one_of {
{hasLower, hasUpper, hasDigit}
{hasLower, hasUpper, hasSymbol}
{hasLower, hasDigit, hasSymbol}
{hasUpper, hasDigit, hasSymbol}
}
loop(8..){ any }
end
}
`)
console.log(pwdRegexp.password)
// /^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*\W)|(?=.*[a-z])(?=.*\d)(?=.*\W)|(?=.*[A-Z])(?=.*\d)(?=.*\W)).{8,}$/

```

## Cheat sheet

| Rexx | RegExp | | Rexx | RegExp |
|-------------------------------------|-----------------|----|----------------|-----------------|
| one_of { 'a', 'b', 'c' } | [abc] | | word | \w |
| one_of { 'foo', 'bar' } | foo\|bar | | non_word | \W |
| one_of { range {'a', 'z'} } | [a-z] | | digit | \d |
| optional {'a'} / loop(0..1) {'a'} | a? | | non_digit | \D |
| optional {'abc'} | (?:abc)? | | whitespace | \s |
| loop(0..) {'a'} | a* | | non_whitespace | \S |
| one_or_more {'a'} / loop(1..) {'a'} | a+ | | boundary | \b |
| loop(2) {'a'} | a{2} | | non_boundary | \B |
| loop(2..3) {'a'} | a{2,3} | | chinese | [\u4e00-\u9fa5] |
| except {'a'} | [^a] | | '\\d' | \d |
| except { range {'a', 'z'} } | [^a-z] | | '\\uffff' | \uffff |
| group{'foo'} | (foo) | | newline | \n |
| group('year'){'2024'} | (?\2024) | | tab | \t |
| ref {1} | \1 | | any | . |
| ref {year} | \k\ | | begin | ^ |
| followed_by {'a'} | (?=a) | | end | $ |
| not_followed_by {'a'} | (?!a) | | global | g |
| preceded_by {'a'} | (?<=) | | ignore_case | i |
| not_preceded_by {'a'} | (?abc).`

### ref

Syntax: `ref { 1 }` or `ref { 'name' }`

References a previously matched group.

Example: `ref { 1 }` or `ref { 'name' }` translates to `\1` or `\k`.

### followed_by

Syntax: `followed_by { 'pattern' }`

Asserts that what follows the current position is the specified pattern.

Example: `followed_by { 'a' }` translates to `(?=a)`.

### not_followed_by

Syntax: `not_followed_by { 'pattern' }`

Asserts that what follows the current position is not the specified pattern.

Example: `not_followed_by { 'a' }` translates to `(?!a)` .

### preceded_by

Syntax: `preceded_by { 'pattern' }`

Asserts that what precedes the current position is the specified pattern.

Example: `preceded_by { 'a' }` translates to `(?<=a)`.

### not_preceded_by

Syntax: `not_preceded_by { 'pattern' }`

Asserts that what precedes the current position is not the specified pattern.

Example: `not_preceded_by { 'a' }` translates to `(?

Packages Code

[Rexx](https://github.com/yyytcool/rexx)

```js
digits = { one_or_more { digit } }

semVer = {
begin
optional {'v'}
group('major') { digits }
'.'
group('minor') { digits }
'.'
group('patch') { digits }
end
}
// /^v?(?\d+)\.(?\d+)\.(?\d+)$/
```

[melody](https://github.com/yoav-lavi/melody)

```js
;
option of "v";
capture major {
some of ;
}
".";
capture minor {
some of ;
}
".";
capture patch {
some of ;
}
;
// /^v?(?\d+)\.(?\d+)\.(?\d+)$/
```

[megic-regexp](https://github.com/unjs/magic-regexp)

```js
import { createRegExp, maybe, oneOrMore, exactly, digit } from 'magic-regexp'

const regExp = createRegExp(
maybe('v')
.and(oneOrMore(digit).groupedAs('major'))
.and(exactly('.'))
.and(oneOrMore(digit).groupedAs('minor'))
.and(exactly('.'))
.and(oneOrMore(digit).groupedAs('patch'))
.at.lineStart()
.at.lineEnd()
)
// /^v?(?\d+)\.(?\d+)\.(?\d+)$/
```

[JSVerbalExpressions](https://github.com/VerbalExpressions/JSVerbalExpressions)

```js
const regExp = VerEx()
.startOfLine()
.maybe('v')
.beginCapture()
.digit().oneOrMore()
.endCapture()
.then('.')
.beginCapture()
.digit().oneOrMore()
.endCapture()
.then('.')
.beginCapture()
.digit().oneOrMore()
.endCapture()
.endOfLine()
// /^(?:v)?(\d+)(?:\.)(\d+)(?:\.)(\d+)$/
```

## Contributing

Contributions to this project are welcome.

Clone and fork:

```sh
git clone https://github.com/yyytcool/rexx.git
```

## License

[Apache License](./LICENSE).

Copyright (c) 2024-present, yyytcool