/\$(\$)?([^]*?)\$(\$)?/
匹配单$
双$
数学公式内容然后进行渲染
分割符号
/(<[^>]+>|\$\$.+?\$\$|\$.+?\$|&[a-zA-Z]{2,8};)/gim
<[^>]+>
:匹配HTML或者XML标签\$\$.+?\$\$
: 匹配类似Latex语法,+?
是非贪婪匹配,尽可能少\$.+?\$
: 同上,双美元是块渲染,单美元是行内渲染&[a-zA-Z]{2,8};
:匹配HTML实体,类似&
是;
|
:是支持多种模式/gim
: 多次匹配,多行模式,大小写不敏感
正则表达式
创建方式主要两种
- RegExp
regexp = new RegExp('patten','flags)
- 字面量
/abc/g
修饰符
常见
- g : 返回全部匹配项
- i : 大小写不敏感
- u : 开启unicode字符支持
- s: 开始点完全匹配模式
- m: 开启锚点多行模式
方法
搜索
字符串.match(正则表达式)
返回匹配的字符数组
没有/g
的话,还有.index
.input
等额外方法
没有匹配项返回null
替换
字符串.replace(正则表达式,replacement)
// 没有修饰符 g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// 带有修饰符 g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
replacement参数
符号 | 在替换字符串中的行为 |
---|---|
$& | 插入整个匹配项 |
`$`` | 插入字符串中匹配项之前的字符串部分 |
$' | 插入字符串中匹配项之后的字符串部分 |
$n | 如果 n 是一个 1-2 位的数字,则插入第 n 个分组的内容,详见 捕获组 |
$<name> | 插入带有给定 name 的括号内的内容,详见 捕获组 |
$$ | 插入字符 $ |
测试
字符串.test(正则表达式)
至少有一个就返回true
,否则返回false
字符类
\d
digit, 0-9
\s
space,类似\n
,\t
这种
\w
word, 字母,数字,下拉线_
反向类
\D
除数字的字符都行
\S
同上
\W
同上
点(.)匹配”所有字符“
点 .
是一种 特殊字符类,它与“除换行符之外的任何字符”匹配。
例如:
alert('Z'.match(/./)) // Z
alert('A\nB'.match(/A.B/s)) // A\nB(匹配了!)
锚点:字符串开始 ^ 和末尾 $
插入符号 ^
和美元符号 $
在正则表达式中具有特殊的含义。它们被称为“锚点”。
插入符号 ^
匹配文本开头,而美元符号 $
则匹配文本末尾。
结合起来,就是可以实现完美匹配了
多行模式 修饰符m
加上了就可以匹配多行开头,多行结尾了
词边界
\b
有三种不同的位置可作为词边界:
- 在字符串开头,如果第一个字符是单词字符
\w
。 - 在字符串中的 两个字符之间,其中一个是单词字符
\w
,另一个不是。 - 在字符串末尾,如果最后一个字符是单词字符
\w
。
集合与范围[...]
集合
在方括号 […]
中的几个字符或者字符类表示“搜索给定字符中的任意一个”。
[QWER]
表示以下 4个字符中的任何一个:'Q'
、'W'
、'E'
或 'R'
。
范围
方括号也可以包含 字符范围。
例如,[a-z]
表示从 a
到 z
范围内的字符,[0-5]
表示从 0
到 5
的数字
[0-9A-F]
中有两个范围:
它搜索一个字符,该字符要么是在 0
到 9
范围内的数字,要么是从 A
到 F
的字母。
排除范围
除了普通的范围匹配,还有像这样 [^…]
的“排除”范围匹配。
通过在开头添加插入符号 ^
来表示匹配所有 除了给定的字符 之外的任意字符。
[^aeyo]
—— 匹配除了'a'
、'e'
、'y'
或'o'
之外的任何字符。[^0-9]
—— 匹配除了数字之外的任何字符,与\D
作用相同。[^\s]
—— 匹配任何非空格字符,与\S
作用相同。
[…] 中的转义
通常当我们想要准确地找到一个特殊字符时,我们需要像 \.
这样对其进行转义。如果我们需要反斜杠,那么我们需要使用 \\
,等等。
在方括号,我们可以使用绝大多数特殊字符而无需转义:
- 符号
. + ( )
无需转义。 - 在开头或结尾(未定义范围)的连字符
-
不会被转义。 - 插入符号
^
仅在开头会被转义(表示排除)。 - 右方括号
]
总是会被转义(如果我们需要寻找那个符号)。
范围和修饰符 “u”
如果集合中有代理对(surrogate pairs),则需要标志 u
才能使它们正常工作。
例如,让我们在字符串 𝒳
中查找 [𝒳𝒴]
:
-
量词(Quantifiers){n}+?*
{n}
确切的位数
{5}` => `\d{5}` === `\d\d\d\d\d
范围
{3,5}
匹配 3-5 个{,5}
匹配最多 5 个{6,}
匹配至少 6 个量词缩写
+
: 一个及以上,==={1,}
\*
: 零个及以上,==={0,}
?
: 零个或一个,==={0,1}
贪婪量词与惰性量词
看一个样例先
let regexp = /".+"/g
let str = 'a "witch" and her "broom" is one'
alert(str.match(regexp)) // "witch" and her "broom"
……可以看出来它的运行结果与我们的预期不同!
在贪婪模式下(默认情况),量词都会尽可能多地重复。
惰性量词(Lazy Quantifiers)
在默认情况下,量词是“贪婪的”,这意味着它们会尽可能多地匹配字符。通过在量词后面加上 ?
,可以将其变为“惰性的”,即尽可能少地匹配字符。
*?
: 零个或多个,尽可能少+?
: 一个或多个,尽可能少??
: 零个或一个,尽可能少{n,m}?
: n 到 m 个,尽可能少{n,}?
: 至少 n 个,尽可能少
示例
假设我们有以下字符串:"aaaaa"
-
贪婪匹配(Greedy Matching)
模式:
a+
匹配结果:
["aaaaa"]
-
惰性匹配(Lazy Matching)
模式:
a+?
匹配结果:
["a", "a", "a", "a", "a"]
捕获组
(...)
称为“捕获组(capturing group)”。
- 它允许将匹配的一部分作为结果数组中的单独项。
- 如果我们将量词放在括号后,则它将括号视为一个整体。
命名组
在左括号后紧跟着放置 ?\<name\>
即可完成对括号的命名。
例如,让我们查找 “year-month-day” 格式的日期:
let dateRegexp = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
let str = "2024-06-18";
let groups = str.match(dateRegexp).groups;
alert(groups.year); // 2024
alert(groups.month); // 06
alert(groups.day); // 18
替换中的捕获组
let str = "John Bull";
let regexp = /(\w+) (\w+)/;
alert( str.replace(regexp, '$2, $1') ); // Bull, John
对于命名的括号,引用为 $<name>
。
非捕获组 ?
有点抽象,回去多试试
有时我们需要用括号才能正确应用量词,但我们不希望它们的内容出现在结果中
::: notice
像搭积木一样,材料越多也越来复杂
:::
模式中的反向引用:\N 和 \k<name>
引入一个任务,我们想要匹配这两种'...'
,"..."
如果使用的模版是['"](.*?)['"]
,则会有下面的问题
let str = `He said: "She's the one!".`
let regexp = /['"](.*?)['"]/g
// 不是我们想要的结果
alert(str.match(regexp)) // "She'
抓虫
{n}
导致了mdx文件崩溃,因为是一个变量