Skip to content

原子

作者:Yuan Tang
更新于:5 个月前
字数统计:1.1k 字
阅读时长:4 分钟

原子表

在一组字符中匹配某个元字符,在正则表达式中通过元字符表来完成,就是放到[] (方括号)中。

使用语法

原子表说明
[]只匹配其中的一个原子
[^]只匹配"除了"其中字符的任意一个原子
[0-9]匹配 0-9 任何一个数字
[a-z]匹配小写 a-z 任何一个字母
[A-Z]匹配大写 A-Z 任何一个字母

实例操作

使用[]匹配其中任意字符即成功,下例中匹配ue任何一个字符,而不会当成一个整体来对待

js
const url = 'tydumpling.com'
console.log(/ae/.test(url)) // false
console.log(/[ae]/.test(url)) // true

日期的匹配

js
const tel = '2022-02-23'
console.log(tel.match(/\d{4}([-\/])\d{2}\1\d{2}/))

获取0~3间的任意数字

js
const num = '2'
console.log(/[0-3]/.test(num)) // true

匹配a~f间的任意字符

js
const fn = 'e'
console.log(/[a-f]/.test(fn)) // true

顺序为升序否则将报错

js
const num = '2'
console.log(/[3-0]/.test(num)) // SyntaxError

字母也要升序否则也报错

js
const fn = 'tydumpling.com'
console.log(/[f-a]/.test(fn)) // SyntaxError

获取所有用户名

js
const fn = `
张三:010-99999999,李四:020-88888888`
const res = fn.match(/[^:\d\-,]+/g)
console.log(res)

原子表中有些正则字符不需要转义,如果转义也是没问题的,可以理解为在原子表中. 就是小数点

js
const str = '(tydumpling.com)+'
console.table(str.match(/[().+]/g))

// 使用转义也没有问题
console.table(str.match(/[\(\)\.\+]/g))

可以使用 [\s\S][\d\D]匹配到所有字符包括换行符

js
...
const reg = /[\s\S]+/g;
...

下面是使用原子表知识删除所有标题

html
<body>
  <p>tydumpling</p>
  <h1>tydumpling.com</h1>
  <h2>fndd.com</h2>
</body>
<script>
  const body = document.body;
  const reg = /<(h[1-6])>[\s\S]*<\/\1>*/g;
  let content = body.innerHTML.replace(reg, "");
  document.body.innerHTML = content;
</script>

原子组

  • 如果一次要匹配多个原子,可以通过原子组完成
  • 原子组与原子表的差别在于原子组一次匹配多个原子,而原子表则是匹配任意一个字符
  • 原字符组用 () 包裹

下面使用原子组匹配 h1 标签,如果想匹配 h2 只需要把前面原子组改为 h2 即可。

js
const fn = '<h1>tydumpling.com</h1>'
console.log(/<(h1)>.+<\/\1>/.test(fn)) // true

基本使用

没有添加 g 模式修正符时只匹配到第一个,匹配到的信息包含以下数据

变量说明
0匹配到的完整内容
1,2....匹配到的原子组
index原字符串中的位置
input原字符串
groups命名分组

match中使用原子组匹配,会将每个组数据返回到结果中

  • 0 为匹配到的完成内容
  • 1/2 等 为原子级内容
  • index 匹配的开始位置
  • input 原始数据
  • groups 组别名
js
const fn = 'tydumpling.com'
console.log(fn.match(/houdun(ren)\.(com)/))
// ["tydumpling.com", "ren", "com", index: 0, input: "tydumpling.com", groups: undefined]

下面使用原子组匹配标题元素

js
const fn = `
  <h1>tydumpling</h1>
  <span>tydumpling</span>
  <h2>fndd</h2>
`

console.table(fn.match(/<(h[1-6])[\s\S]*<\/\1>/g))

检测 0~100 的数值,使用 parseInt 将数值转为 10 进制

js
console.log(/^(\d{1,2}|100)$/.test(parseInt(09, 10)));

邮箱匹配

下面使用原子组匹配邮箱

js
const fn = '2300071698@qq.com'
const reg = /^[\w\-]+@[\w\-]+\.(com|org|cn|cc|net)$/i
console.dir(fn.match(reg))

如果邮箱是以下格式 tydumpling@fn.com.cn 上面规则将无效,需要定义以下方式

js
const fn = 'admin@tydumpling.com.cn'
const reg = /^[\w-]+@([\w-]+\.)+(org|com|cc|cn)$/
console.log(fn.match(reg))

引用分组

\n 在匹配时引用原子组, $n 指在替换时使用匹配的组数据。下面将标签替换为p标签

js
const fn = `
  <h1>tydumpling</h1>
  <span>tydumpling</span>
  <h2>fndd</h2>
`

const reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi
console.log(fn.replace(reg, '<p>$2</p>'))

如果只希望组参与匹配,便不希望返回到结果中使用 (?: 处理。下面是获取所有域名的示例

js
const fn = `
  https://www.tydumpling.com
  http://tydumpling.github.io.com
  https://fndd.com
`

const reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/gi
while ((v = reg.exec(fn)))
  console.dir(v)

分组别名

如果希望返回的组数据更清晰,可以为原子组编号,结果将保存在返回的 groups字段中

js
const fn = '<h1>tydumpling.com</h1>'
console.dir(fn.match(/<(?<tag>h[1-6])[\s\S]*<\/\1>/))

组别名使用 ?<> 形式定义,下面将标签替换为p标签

js
const fn = `
  <h1>tydumpling</h1>
  <span>tydumpling</span>
  <h2>fndd</h2>
`
const reg = /<(?<tag>h[1-6])>(?<con>[\s\S]*)<\/\1>/gi
console.log(fn.replace(reg, '<p>$<con></p>'))

获取链接与网站名称组成数组集合

html
<body>
  <a href="https://www.tydumpling.com">tydumpling</a>
  <a href="https://www.fndd.com">fndd</a>
  <a href="https://www.sina.com.cn">新浪</a>
</body>

<script>
  let body = document.body.innerHTML;
  let reg = /<a\s*.+?(?<link>https?:\/\/(\w+\.)+(com|org|cc|cn)).*>(?<title>.+)<\/a>/gi;
  const links = [];
  for (const iterator of body.matchAll(reg)) {
    links.push(iterator["groups"]);
  }
  console.log(links);
</script>

Contributors

Yuan Tang