前言
正则表达式是处理字符串的强大工具,在 TypeScript/JavaScript 中同样适用。本文将带你全面了解正则表达式在 TS 中的用法,包括基础语法、高级技巧和实际应用场景。
一、正则表达式基础
1. 创建正则表达式
1. 字面量语法
基本语法
const regex = /pattern/flags;
-
pattern
: 正则表达式的主体模式 -
flags
: 可选的修饰符(如i
,g
,m
等)
特点
- 在脚本加载时编译(当正则表达式是常量时性能更好)
- 更简洁直观的语法
- 不需要转义反斜杠(
)
2. 构造函数语法
基本语法
const regex = new RegExp('pattern', 'flags');
或
const regex = new RegExp(/pattern/, 'flags');
特点
- 在运行时编译正则表达式
- 可以使用变量动态构建正则表达式
- 字符串中的反斜杠需要转义(
\
) - 可以基于已有的正则对象创建新的正则
何时使用哪种方式
-
使用字面量语法:
-
正则模式是固定的、已知的
-
不需要动态构建正则
-
需要更好的可读性
-
-
使用构造函数语法:
- 需要动态构建正则表达式(如基于用户输入)
动态构建
在程序运行时(而非编写代码时)根据需要创建或修改正则表达式模式。
- 正则模式需要从变量或配置中获取
- 需要在运行时组合多个正则片段
2. 常用修饰符(flags)
1.i(ignoreCase) – 不区分大小写
作用:使匹配不区分大小写
const regex = /hello/i; console.log(regex.test('Hello')); // true console.log(regex.test('HELLO')); // true console.log(regex.test('hello')); // true console.log(regex.test('hElLo')); // true
2.g(global) – 全局匹配
作用:查找所有匹配项,而不是在第一个匹配后停止
const str = 'apple, orange, apple, banana'; const regex = /apple/g; let match; while ((match = regex.exec(str)) !== null) { console.log(`Found '${match[0]}' at index ${match.index}`); } // 输出: // Found 'apple' at index 0 // Found 'apple' at index 15
3.m(multiline) – 多行模式
作用:使 ^
和 $
匹配每行的开头和结尾,而不是整个字符串的开头和结尾
const multiLineText = `First line Second line Third line`; // 不使用 m 修饰符 console.log(/^Second/.test(multiLineText)); // false //在整个字符串的开头位置尝试匹配 "Second" // 使用 m 修饰符 console.log(/^Second/m.test(multiLineText)); // true
4.u(unicode) – Unicode 模式
作用:正确处理大于 uFFFF
的 Unicode 字符
const emojiText = '😊 笑脸'; // 不使用 u 修饰符 console.log(/^.$/.test(emojiText)); // false (无法正确匹配emoji) // 使用 u 修饰符 console.log(/^.$/u.test(emojiText)); // true (正确匹配单个emoji字符) // 匹配特定Unicode字符 console.log(/p{Emoji}/u.test('😊')); // true console.log(/p{Script=Han}/u.test('汉')); // true (匹配汉字)
5.s(dotAll) – dotAll 模式
作用:使 .
匹配包括换行符在内的任意字符
const textWithNewline = 'HellonWorld'; // 不使用 s 修饰符 console.log(/Hello.World/.test(textWithNewline)); // false (.不匹配换行符) // 使用 s 修饰符 console.log(/Hello.World/s.test(textWithNewline)); // true // 替代方案(不使用s修饰符) console.log(/Hello[sS]World/.test(textWithNewline)); // true
组合使用多个修饰符
可以同时使用多个修饰符,顺序无关紧要:
// 不区分大小写 + 全局匹配 + 多行模式 const regex = /^hello/gim; const text = `Hello world hello everyone HELLO there`; console.log(text.match(regex)); // ["Hello", "hello", "HELLO"]
二、正则表达式语法详解
1. 字符匹配
模式 | 描述 |
---|---|
. |
匹配除换行符外的任意字符 |
d |
匹配数字,等价于 [0-9] |
D |
匹配非数字,等价于 [^0-9] |
w |
匹配字母、数字或下划线 |
W |
匹配非字母、数字、下划线 |
s |
匹配空白字符(空格、制表符等) |
S |
匹配非空白字符 |
2. 量词
模式 | 描述 |
---|---|
* |
匹配前一个表达式 0 次或多次 |
+ |
匹配前一个表达式 1 次或多次 |
? |
匹配前一个表达式 0 次或 1 次 |
{n} |
匹配前一个表达式恰好 n 次 |
{n,} |
匹配前一个表达式至少 n 次 |
{n,m} |
匹配前一个表达式 n 到 m 次 |
3. 位置匹配
模式 | 描述 |
---|---|
^ |
匹配输入的开始。如,^abc 表示字符串必须以 abc 开头。 |
$ |
匹配输入的结束。如,abc$ 表示字符串必须以 abc 结尾。 |
b |
匹配单词边界 |
B |
匹配非单词边界 |
4.字符类
模式 | 描述 |
---|---|
[] |
定义一个字符类,匹配方括号内的任意一个字符。例如,[abc] 可以匹配 a 、b 或 c 。 |
[^] |
表示取反,匹配不在方括号内的任意一个字符。例如,[^abc] 可以匹配除 a 、b 、c 之外的任意字符。 |
[a-z] 、[A-Z] 、[0-9] 等 |
表示范围,分别匹配小写字母、大写字母和数字。 |
三、TypeScript 中的正则方法
1. RegExp 方法
const regex = /hello/; // test() - 测试是否匹配 regex.test('hello world'); // true // exec() - 执行搜索,返回匹配结果或 null const result = regex.exec('hello world'); console.log(result?.[0]); // "hello"
2. String 方法
const str = 'Hello world, hello TypeScript'; // match() - 返回匹配结果 str.match(/hello/gi); // ["Hello", "hello"] // search() - 返回匹配位置的索引 str.search(/world/); // 6 // replace() - 替换匹配的子串 str.replace(/hello/gi, 'Hi'); // "Hi world, Hi TypeScript" // split() - 使用正则分割字符串 'one,two,three'.split(/,/); // ["one", "two", "three"]
四、实际应用示例
1. 验证邮箱格式
function isValidEmail(email: string): boolean { const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/; return emailRegex.test(email); }
1.^- 匹配字符串开始
确保匹配从字符串开头开始,防止前面有其他字符
2.[^s@]+- 本地部分(local-part)
-
[^s@]
:字符类,匹配任何不是空白字符(s
)也不是@符号的字符 -
+
:匹配前面的元素一次或多次 - 效果:匹配一个或多个非空白、非@的字符
3.@- 匹配@符号
邮箱地址必须包含一个@符号
4.[^s@]+- 域名第一部分
- 同上,匹配@和点号之间的部分
- 例如在
user@example.com
中匹配example
5..- 匹配点号
- 转义的点号,匹配实际的
.
字符 - 域名必须包含一个点号
正则表达式中的点号.
- 在正则中,未转义的点号
.
是一个特殊字符 - 它表示匹配除换行符外的任意单个字符
- 例如
a.c
可以匹配 “abc”、“a c”、“a$c” 等
转义点号.
- 当我们需要匹配实际的点号字符时,必须转义它
- 使用反斜杠
进行转义:
.
- 这样
.
就表示字面的点号字符 “.” 而不是通配符
6.[^s@]+- 顶级域名(TLD)
- 匹配点号后的部分
- 例如在
example.com
中匹配com
7.$- 匹配字符串结束
确保匹配直到字符串结束,防止后面有其他字符
完整匹配流程
以邮箱 username@example.com
为例:
-
^
从字符串开始 -
[^s@]+
匹配username
-
@
匹配@
-
[^s@]+
匹配example
-
.
匹配.
-
[^s@]+
匹配com
-
$
确保字符串结束
2. 提取URL中的参数
function getUrlParams(url: string): Record { const params: Record = {}; const paramRegex = /[?&]([^=#]+)=([^]*)/g; let match; while ((match = paramRegex.exec(url)) !== null) { params[match[1]] = match[2]; } return params; }
正则表达式解析
核心的正则表达式是 /[?&]([^=#]+)=([^]*)/g
,让我们分解它的每个部分:
1.[?&]
- 匹配
?
或&
字符 -
?
开始查询参数部分 -
&
分隔多个参数
2.([^=#]+)
- 第一个捕获组
()
,匹配参数名 -
[^=#]
匹配任何不是=
或#
的字符 -
+
表示匹配一个或多个这样的字符
3.=
- 匹配字面的等号,分隔参数名和值
4.([^]*)
- 第二个捕获组
()
,匹配参数值 -
[^]
匹配任何不是&
或#
的字符 -
*
表示匹配零个或多个这样的字符(允许空值)
5./g
- 全局标志,匹配所有符合条件的结果
匹配过程示例
对于 URL http://example.com?name=John&age=25#section1
:
- 第一次匹配:
- 匹配
?name=John
-
match[1]
= “name” -
match[2]
= “John”
- 匹配
- 第二次匹配:
- 匹配
&age=25
-
match[1]
= “age” -
match[2]
= “25”
- 匹配
- 遇到
#
停止匹配
执行流程
- 初始化空对象
params
存储结果 - 使用
while
循环和regex.exec()
遍历所有匹配 - 每次匹配:
-
match[1]
是参数名 -
match[2]
是参数值 - 将键值对存入
params
对象
-
- 返回最终的
params
对象
3. 密码强度验证
function checkPasswordStrength(password: string): 'weak' | 'medium' | 'strong' { // 至少8个字符 if (password.length
1. 检查纯字母或纯数字
/^[a-zA-Z]+$/ // 纯字母 /^d+$/ // 纯数字
-
^
和$
确保整个字符串匹配 -
[a-zA-Z]
匹配任何大小写字母 -
d
匹配数字 -
+
表示一个或多个
2. 检查同时包含字母和数字
/^(?=.*[a-zA-Z])(?=.*d).+$/
-
(?=.*[a-zA-Z])
正向先行断言,确保字符串包含字母 -
(?=.*d)
正向先行断言,确保字符串包含数字
正向先行断言(?=.*)
基本语法
(?=pattern)
是正向先行断言的基本形式,表示:
- 当前位置后面必须能匹配
pattern
- 但匹配后,正则引擎的当前位置不会改变
(?=.*[a-zA-Z])(?=.*d)解析
这个表达式由两个正向先行断言组成,分别检查密码中是否包含字母和数字。
第一个断言 (?=.*[a-zA-Z])
-
.*
:
-
.
匹配任意字符(除换行符) -
*
表示零次或多次 -
.*
组合表示”任意数量的任意字符”
-
[a-zA-Z]
:
- 匹配任意大小写字母
- 整体含义:
- 在字符串的任意位置(因为
.*
)后面必须有一个字母 - 相当于”字符串中必须包含至少一个字母”
第二个断言 (?=.*d)
-
d
:
- 匹配任意数字(等价于
[0-9]
)
- 整体含义:
- 在字符串的任意位置后面必须有一个数字
- 相当于”字符串中必须包含至少一个数字”
组合效果
/^(?=.*[a-zA-Z])(?=.*d).+$/
表示:
-
^
从字符串开头开始 -
(?=.*[a-zA-Z])
断言:后面某处必须有一个字母 -
(?=.*d)
断言:后面某处必须有一个数字 -
.+
实际匹配:一个或多个任意字符 -
$
直到字符串结束
-
.+
匹配整个字符串(至少一个字符)
3. 检查包含特殊字符
/^(?=.*[a-zA-Z])(?=.*d)(?=.*[^a-zA-Zd]).+$/
-
(?=.*[^a-zA-Zd])
正向先行断言,确保字符串包含非字母非数字的字符(即特殊字符) -
[^a-zA-Zd]
匹配任何不是字母也不是数字的字符
总结
到此这篇关于TypeScript中正则表达式的用法及实际应用的文章就介绍到这了,更多相关TS中正则表达式内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!