0.4.0 • Published 4 years ago
@josephuspaye/match-common-formats v0.4.0
match-common-formats
Match a piece of text to common formats like URLs, email addresses, colors, and more.
Due to the large number of formats to match, this project is completed in parts:
- Part 1: URIs (URIs + URNs + URLs) and IP Addresses (IPv4 + IPv6): Published in v0.1.0.
- Part 2: Colors - RGB hexadecimal (8, 6, 4, and 3-character codes);
rgb()
,rgba()
,hsl()
, andhsla()
(with comma and space separators): Published in v0.2.0. - Part 3: Email addresses and social tokens (@mentions and #hashtags): Published in v0.3.0.
- Part 4: Currency (e.g. 2,000AUD or LRD2,000,000.75): Published in v0.4.0.
This project is part of #CreateWeekly, my attempt to create something new publicly every week in 2020.
Demo
Installation
npm install -g @josephuspaye/match-common-formats
Usage
Match with all matchers
The following example shows how to match a piece of text with all matchers:
import { match } from '@josephuspaye/match-common-formats';
const first = match('example.com'); // matches a URL
const second = match('192.168.0.1'); // matches an IP address
const third = match('hello@example.com'); // matches an email address and a URL
console.log({ first, second, third });
{
"first": [
{
"type": "url",
"label": "Web URL",
"input": "example.com",
"url": "http://example.com",
"scheme": "http"
}
],
"second": [
{
"type": "ip-address",
"label": "IPv4 Address",
"input": "192.168.0.1",
"version": "ipv4",
"address": "192.168.0.1"
}
],
"third": [
{
"type": "email-address",
"label": "Email Address",
"input": "hello@example.com",
"address": "hello@example.com"
},
{
"type": "url",
"label": "Web URL",
"input": "hello@example.com",
"url": "http://hello@example.com",
"scheme": "http"
}
]
}
Stop matching after first match
The following example shows how to match a piece of text with all matchers, stopping after the first match:
import { match } from '@josephuspaye/match-common-formats';
// Would normally match a hex color code and a hashtag, but specifying `matchOne`
// stops after the first match, returning only the color match
const matches = match('#bad', { matchOne: true });
console.log({ matches });
{
"matches": [
{
"input": "#bad",
"expected": [
{
"type": "color",
"label": "Hexadecimal Color Code",
"input": "#bad",
"format": "hex",
"color": "#bad"
}
]
}
]
}
Match with select matchers
The following example shows how to match a piece of text with select matchers:
import {
match,
matchUri,
matchIpAddress,
} from '@josephuspaye/match-common-formats';
const first = match('example.com', { matchers: [matchUri] });
const second = match('example.com', { matchers: [matchIpAddress] }); // matches will be empty
console.log({ first, second });
{
"first": [
{
"type": "url",
"label": "Web URL",
"input": "example.com",
"url": "http://example.com",
"scheme": "http"
}
],
"second": []
}
Match with a specific matcher
The following example shows how to match a piece of text with a specific matcher:
import { match, matchIpAddress } from '@josephuspaye/match-common-formats';
const first = matchIpAddress('10.0.0.1');
const second = matchIpAddress('example.com'); // no match
console.log({ first, second });
{
"first": {
"type": "ip-address",
"label": "IPv4 Address",
"input": "10.0.0.1",
"version": "ipv4",
"address": "10.0.0.1"
},
"second": null
}
Available formats
Format | Type | Input example |
---|---|---|
URI | uri (data ) | data:image/png;base64,... |
URN | urn (isbn ) | urn:isbn:0451450523 |
URL | url (http ) | get.pizza |
URL | url (https ) | https://example.com |
URL | url (http ) | localhost:3000 |
IP Address | ip-address (ipv4 ) | 127.0.0.1 |
IP Address | ip-address (ipv6 ) | ::1 |
RGB Color (Hex) | color (hex ) | #bad , #bada55 , #abcd , #aabbccdd |
RGB Color | color (rgb ) | rgb(22, 22, 22) |
RGB Alpha Color | color (rgba ) | rgba(22, 22, 22, 0.5) |
HSL Color | color (hsl ) | hsl(22deg, 50%, 20%) |
HSL Alpha Color | color (hsla ) | hsla(22deg, 50%, 20%, 80%) |
Email address* | email-address | john.doe+newsletters@example.com |
Social token (mention) | mention | @JosephusPaye |
Social token (hashtag) | hashtag | #CreateWeekly |
Currency | currency | 2,000,000LRD |
Currency | currency | AUD2000.00 |
Notes
- The email address matcher is not technically "complete", as it doesn't match addresses with unknown TLDs, IP addresses, or special characters in the local part that are not
+
,-
,_
, or.
. It is designed to match only a subset of technically valid email address, ones that are more "common".
API
interface MatchCommon {
type: string;
label: string;
input: string;
}
interface Url extends MatchCommon {
type: 'url';
url: string;
scheme: string;
}
interface Uri extends MatchCommon {
type: 'uri';
uri: string;
scheme: string;
}
interface Urn extends MatchCommon {
type: 'urn';
urn: string;
namespaceId: string;
namespaceString: string;
}
interface IpAddress extends MatchCommon {
type: 'ip-address';
version: 'ipv4' | 'ipv6';
address: string;
}
interface Color extends MatchCommon {
type: 'color';
format: 'hex' | 'rgb' | 'rgba' | 'hsl' | 'hsla';
color: string;
}
interface EmailAddress extends MatchCommon {
type: 'email-address';
address: string;
}
interface SocialToken extends MatchCommon {
type: 'mention' | 'hashtag';
/**
* The mention or hashtag, with the @ or # prefix
*/
token: string;
}
interface KnownCurrency {
code: string;
name: string;
symbol: string;
otherSymbols?: string[];
}
interface Currency extends MatchCommon {
type: 'currency';
currency: KnownCurrency;
amount: number;
}
type Match =
| Uri
| Url
| Urn
| IpAddress
| Color
| EmailAddress
| SocialToken
| Currency;
type Matcher = (string: string) => Match | null;
interface MatchOptions {
/**
* A list of matchers to apply, defaults to all matchers
*/
matchers?: Matcher[];
/**
* Stop matching after the first match
* @default false
*/
matchOne?: boolean;
}
/**
* The default matchers
*/
const defaultMatchers: Matcher[];
/**
* Match the given string to a URN, URL, or URI
*/
function matchUri(string: string): Url | Uri | Urn | null;
/**
* Match the given string to an IPv4 or IPv6 address
*/
function matchIpAddress(string: string): IpAddress | null;
/**
* Match the given string to a hex (RGB), rgb(), rgba(), hsl(), or hsla() color code
*/
function matchColor(string: string): Color | null;
/**
* Match the given string to an email address
*/
function matchEmailAddress(string: string): EmailAddress | null;
/**
* Match the given string to a social token (@mention or #hashtag)
*/
function matchSocialToken(string: string): SocialToken | null;
/**
* Match the given string to a currency value
*/
function matchCurrency(
string: string,
options?: {
matchSymbol?: boolean;
decimalSymbol?: ',' | '.';
thousandSeparator?: ',' | '.' | ' ';
}
): Currency | null;
/**
* Compare the given string to known formats, optionally only those
* matched by the given matchers, and get the matches
*/
function match(string: string, options?: MatchOptions): Match[];