Skip to content
索引

正则表达式

基础规则

  • . 表示除换行符以外的所有字符
  • ^表示开始位置严格匹配,必须按规定的正则开始,否则返回false
  • $表示结束位置严格匹配,必须按规定的正则结束,否则返回false
  • \d\w\s分别匹配数字、字符、空格
  • \D\W\S分别匹配非数字、非字符、非空格
  • [abc] 匹配 a、b 或 c 中的一个字母
  • [a-z] 匹配 a 到 z 中的一个字母
  • [^abc] 匹配除了 a、b 或 c 中的其他字母
  • aa|bb 匹配 aa 或 bb
  • ? 匹配 0 次或 1 次
  • *匹配 0 次或多次
  • + 匹配 1 次或多次

示例:

  1. 正则/\d/,匹配字符串为a123,从第一个字符依次匹配,发现存在数字1,符合正则,返回true,加上^后,正则为/^\d/,发现第一个字符是a,返回false
  2. 正则/\d/,匹配字符串为123a,从第一个字符依次匹配,发现存在数字1,符合正则,返回true,加上$后,正则为/\d$/,发现末尾是a,返回false

判断 HTML 标签是否闭合

js
/^<(\w+)[^>]*>.*?<\/\1>$/
/^<(\w+)[^>]*>.*?<\/\1>$/

这个正则表达式使用了前后断言,其中:

  • ^ 表示匹配输入的开始位置
  • <(\w+) 匹配以 < 开头的标签,括号内为标签名,\w+ 表示匹配一个或多个字母、数字、下划线。
  • [^>]* 匹配不包含 > 的任意字符,* 表示匹配零个或多个字符。
  • .*? 匹配任意字符,*? 表示非贪婪模式,尽可能少的匹配字符,避免匹配到下一个标签。
  • <\/\1> 匹配以 < 开头、\/ 表示 / 字符,\1 表示与前面的括号内的第一个子匹配相同的文本,即匹配前面捕获到的标签名,> 表示标签的结束。

这个正则表达式可以用于匹配单个 HTML 标签,且要求该标签是闭合的。

js
/<([a-zA-Z]+)(?:\s+[^>]+)?>(?:.*?<\/\1>)?$/gm
/<([a-zA-Z]+)(?:\s+[^>]+)?>(?:.*?<\/\1>)?$/gm

这个正则表达式的实现和上面的正则表达式类似,但有以下不同之处:

  • <([a-zA-Z]+) 中的 \w+ 被替换为 [a-zA-Z]+,只匹配字母。
  • (?:\s+[^>]+)? 匹配空格符加上非 > 的字符,(?:...) 表示非捕获分组。
  • (?:.*?<\/\1>)? 匹配任意字符和 <\/\1>? 表示该分组出现零次或一次。

这个正则表达式可以匹配闭合的 HTML 标签,也可以匹配未闭合的标签,例如 <img>。使用了全局匹配标记 g 和多行匹配标记 m

总的来说,这两个正则表达式都可以用于匹配 HTML 标签,但是在实现方式和使用场景上有些不同。第一个正则表达式用于匹配单个标签,第二个正则表达式可以匹配多个标签,包括未闭合的标签。

括号()

js
/^<(\w+)[^>]*>.*?<\/\1>$/
/^<(\w+)[^>]*>.*?<\/\1>$/

括号在正则表达式中称为分组,用于将匹配到的子字符串捕获到分组中。在这个正则表达式中,<(\w+)表示匹配以尖括号<开头,后面紧跟一个或多个字母或数字(\w+),并且将这个字母或数字捕获到第一个分组中

在正则表达式中,捕获到分组可以用于后续的操作,例如替换、匹配等。在这个正则表达式中,捕获到的分组可以用于后面的</\1>,表示匹配和第一个分组相同的结束标签。这样就可以匹配类似于<div>...</div>、<p>...</p>等成对出现的标签,并且可以保证起始标签和结束标签的标签名相同

方括号[]

在正则表达式中,方括号[]表示一个字符集,用于匹配其中的任意一个字符。而方括号中的^符号表示取反,即匹配除了里面列出的字符以外的任意一个字符。

在这个正则表达式中,[^>]*表示匹配零个或多个非>字符。这个表达式的作用是,匹配以<开头的标签,它们之后的任意字符直到最近的>符号之前,这样可以确保匹配到的标签是一个完整的标签,而不是包含其他标签或者不完整的标签

捕获分组的引用

</\1> 是一个闭合标签的正则表达式,其中 \1 表示对第一个捕获分组的引用,也就是和开头尖括号里的标签名相同的闭合标签。例如,如果开头尖括号里的标签是 <div>,那么闭合标签就应该是 </div>。这个正则表达式的作用是确保匹配到的闭合标签和开头尖括号里的标签名相同,从而保证了标签的正确闭合

贪婪匹配和非贪婪匹配

在正则表达式中,匹配模式通常是尽可能多的匹配符合条件的字符串,这被称为“贪婪匹配”,也就是在不影响整个正则表达式匹配的前提下,尽可能多的匹配字符

举个例子,假设有一个字符串 "hello world, hello chatgpt",我们想要匹配其中的 "hello""world",可以使用正则表达式 /hello.world/,这里的 . 表示匹配任意字符(除了换行符)零次或多次。因为 .* 是贪婪匹配,所以会匹配最长的符合条件的字符串,即 "hello world, hello",而不是我们想要的 "hello""world"

如果希望匹配尽可能短的符合条件的字符串,则可以使用非贪婪匹配,也被称为懒惰匹配。在正则表达式中,使用 ? 符号表示非贪婪匹配。

在上面的例子中,可以将正则表达式修改为 /hello.?world/,这里的 .? 表示匹配任意字符(除了换行符)零次或多次,但尽可能少的匹配。这样就会匹配到我们想要的 "hello""world",而不是最长的符合条件的字符串

在正则表达式中,. 表示匹配除换行符以外的任意字符,* 表示匹配前面的元素零次或多次,而 ? 表示尽可能少的匹配。所以,.*? 表示匹配任意字符(除了换行符)零次或多次,但尽可能少的匹配,即非贪婪匹配。

在这个正则表达式中,.*? 匹配标签之间的任意内容,但是只要遇到了下一个表达式 </\1>,也就是匹配到了和开头尖括号里的标签名相同的闭合标签,就停止匹配。因为 .*? 是非贪婪匹配,所以匹配结果是最短的,也就是从开头尖括号后面的属性部分直到和开头尖括号里的标签名相同的闭合标签之间的内容

获取所有正则匹配结果

js
const s = `<div class="myApp">
    <p class="title">我的应用</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myAppList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
    <p class="title">我的收藏</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myScList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
  </div>`

// 获取html标签中的内容
function delHtmlTag(str) {
  return str.replace(/<[^>]+>/g, "")
}
const str = delHtmlTag(s)
console.log(str)

// 获取所有html标签
console.log(s.match(/<[^>]+>/g))
const s = `<div class="myApp">
    <p class="title">我的应用</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myAppList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
    <p class="title">我的收藏</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myScList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
  </div>`

// 获取html标签中的内容
function delHtmlTag(str) {
  return str.replace(/<[^>]+>/g, "")
}
const str = delHtmlTag(s)
console.log(str)

// 获取所有html标签
console.log(s.match(/<[^>]+>/g))

获取所有正则匹配索引

js
var str = "The rain in Spain stays mainly in the plain"
var patt1 = /ain/g

while (patt1.test(str) == true) {
  console.log("'ain' found. Index now at: " + patt1.lastIndex)
}

var str = "The rain in Spain stays mainly in the plain"
var patt1 = /ain/g

while (patt1.test(str) == true) {
  console.log("'ain' found. Index now at: " + patt1.lastIndex)
}

js
var arr = ["foo", "bar"],
  arr2 = [],
  str = "foo bar flub alien alcohol foo bar foo"
for (var j = 0; j < arr.length; j++) {
  var re = new RegExp(arr[j], "ig")
  while ((match = re.exec(str))) {
    arr2.push({ string: match[0], index: match.index })
  }
}

console.log(arr2)
var arr = ["foo", "bar"],
  arr2 = [],
  str = "foo bar flub alien alcohol foo bar foo"
for (var j = 0; j < arr.length; j++) {
  var re = new RegExp(arr[j], "ig")
  while ((match = re.exec(str))) {
    arr2.push({ string: match[0], index: match.index })
  }
}

console.log(arr2)

判断特殊字符

js
const regexp = RegExp(
  /[(\ )(\~)(\!)(\@)(\#)(\$)(\%)(\^)(\&)(\*)()()()(\-)(\_)(\+)(\=)()()()(\{)(\})(\|)(\\)(\;)(\:)(\')(\")(\,)(\.)(\/)(\<)(\>)(\?)(\)]+/
)
const regexp = RegExp(
  /[(\ )(\~)(\!)(\@)(\#)(\$)(\%)(\^)(\&)(\*)()()()(\-)(\_)(\+)(\=)()()()(\{)(\})(\|)(\\)(\;)(\:)(\')(\")(\,)(\.)(\/)(\<)(\>)(\?)(\)]+/
)

去除特殊字符

js
txt.replace(/[.,;':]/g, '')
txt.replace(/[.,;':]/g, '')

判断中文

js
!/[^\u4e00-\u9fa5]/.test(str)
!/[^\u4e00-\u9fa5]/.test(str)

删除html字符串中所有标签

js
const s = `  <div class="myApp">
    <p class="title">我的应用</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myAppList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
    <p class="title">我的收藏</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myScList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
  </div>`
function delHtmlTag(str) {
  return str.replace(/<[^>]+>/g, "")
 }
const str = delHtmlTag(s)
console.log(str)
const s = `  <div class="myApp">
    <p class="title">我的应用</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myAppList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
    <p class="title">我的收藏</p>
    <div class="app-list">
      <div class="app-item" v-for="(item, index) in myScList" :key="index" @click="clickApp(item)">
        <img :src="item.serverUrl" />
        <p>{{ item.name }}</p>
      </div>
    </div>
  </div>`
function delHtmlTag(str) {
  return str.replace(/<[^>]+>/g, "")
 }
const str = delHtmlTag(s)
console.log(str)

vscode正则替换

选择正则匹配,要加上括号,才能用$字符站位匹配文本

(window.open[^)]*)
$1+"token="+localStorage.getItem('token')
(window.open[^)]*)
$1+"token="+localStorage.getItem('token')

去除所有注释

//.*

Released under the MIT License.