Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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.
- Host: GitHub
- URL: https://github.com/yyytcool/rexx
- Owner: yyytcool
- License: apache-2.0
- Created: 2024-01-30T09:08:35.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2024-02-06T04:01:13.000Z (11 months ago)
- Last Synced: 2024-11-07T22:44:36.983Z (2 months ago)
- Topics: regex, regexp, regular-expressions
- Language: JavaScript
- Homepage: https://yyytcool.github.io/rexx/
- Size: 20.5 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-regex - Rexx - A template tag that uses structured syntax with variables and comments. (JavaScript regex libraries / Abstracted regex syntax)
README
🦖 Rexx
🎮  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