电邮地址
export const Email = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/
- \w 即为 [a-zA-Z0-9_]
- [] 表示一个字符范围,就是一个整体,无需 () 包围
- Gmail 等服务商还支持形如 name.filter@gmail.com 这样的用户别名邮箱
- (.[a-zA-Z0-9_-]{2,3}){1,2} 只适用于前些年常见的 .cn、.com.cn 一类根域名,近几年新增的 .name、.info、.club、.camp 等域名就失效了,形如 vip.xxmail.com 的多级域名也不适用
手机号码
其实以下只适用于中国大陆手机号,其它国家手机号似乎与固定电话号之间没有明显的区分。
export const Mobile = /^1[3-9]\d{9}$/;
- \d 即为 [0-9]
- 中国大陆手机号第二位目前没有 1、2
固话号码
中国大陆固定电话号码“区号 + 机号”始终为 11 位。
export const Phone = /^((0\d{2}-)?\d{8}|(0\d{3}-)?\d{7})$/;
网址
export const URL = /^\w+:\/\/\S+$/;
- URL 协议不仅包括 http、https,还有 ftp(文件传输)、file(本机文件系统)、ed2k(电驴 2000)等各种各样的网络协议
- URL 主机名、路径可以是Unicode 中各种可见字符,但遇到空白符就结束
日期格式
判断是否为合法的日期格式除了用正则之外,还可利用 Date构造函数内部的算法:
export const isDate = raw => !isNaN(+new Date(raw))
- 对于无法解析为日期的数据,date.toString() 会返回“Invalid Date”,date.getTime() 对应的返回值则是 NaN。而算数运算符会调用对象的 valueOf() 方法,date.valueOf() 的返回值又与 date.getTime() 相同。
汉字
“汉字”在计算机领域的学名叫中日韩统一表意文字(俗称 CJK),在 2017 年 6 月发布的 Unicode 10 标准中,它有了代码级明确的指代:
export const HanZi = /\p{Unified_Ideograph}/u;
阿拉伯数字转中文
ECMA-402 标准(ECMAScript 国际化 API)把各语言之间的数据格式转换算法都封装好了,我们引入 polyfill 就可以直接用:
export const toChineseNumber = raw =>
new Intl.NumberFormat('zh-Hans-u-nu-hanidec').format(raw)
数据类型
判断一个值的类型,用比较构造函数名或类名的方式兼容性比较差,因为线上环境通常是压缩后的代码,自定义的函数名、类名不再是原名,应用开发者一般也不会实现 Symbol.toStringTag getter 类成员,导致 Object.prototype.toString.call() 只会返回默认值 [object Object]。
export const isType = (value, constructor) =>
Object(value) instanceof constructor;
- Object 构造函数会返回所有基本值的包装对象
TypeScript
下面,我再给出一个 TypeScript 的实现,让类型推断更加准确:
export function isType<T>(
value: T, constructor: { new(...data: any[]): T }
): value is T {
return Object(value) instanceof constructor;
}
import { isType } from './utility';
let test;
if (isType(test, Number)) console.log(test!.toFixed(2));
浏览器检测
以下使用 globalThis 是为了兼容浏览器主线程、Web Worker、Node.js、Deno 等不同 JavaScript 运行时环境。
//品牌
export const isBrowserVendor = (name, UA = globalThis.navigator?.userAgent || '') =>
UA.toLowerCase().includes(name);
// 爬虫
export const isRobot = (UA = globalThis.navigator?.userAgent || '') =>
/bot|spider|crawler/i.test(UA);
去除 HTML 标签
以下使用了 non-greedy(非贪婪模式)来提升性能,并规避正文中可能出现的示例代码没完全转译尖括号,导致删除错误。
export const removeHtmlTag = raw => raw.replace(/<[\s\S]+?>/g, '');
DOM API
下面再提供一直借助 DOM 引擎的实现:
const box = document.createElement('template');
export function removeHtmlTag(raw) {
box.innerHTML = raw;
return box.content.textContent;
}
URL 参数追加
URL()、URLSearchParams() 在浏览器主线程、Web Worker、Node.js 10+、Deno 均全局可用。
export function appendQuery(path, data, base = globalThis.location.href) {
const URI = new URL(path, base);
const { searchParams } = URI;
for (const key in data) searchParams.append(key, data[key]);
return URI + '';
}