TypeScript中正則表達(dá)式的用法及實際應(yīng)用
前言
正則表達(dá)式是處理字符串的強(qiáng)大工具,在 TypeScript/JavaScript 中同樣適用。本文將帶你全面了解正則表達(dá)式在 TS 中的用法,包括基礎(chǔ)語法、高級技巧和實際應(yīng)用場景。
一、正則表達(dá)式基礎(chǔ)
1. 創(chuàng)建正則表達(dá)式
1. 字面量語法
基本語法
const regex = /pattern/flags;
pattern: 正則表達(dá)式的主體模式flags: 可選的修飾符(如i,g,m等)
特點
- 在腳本加載時編譯(當(dāng)正則表達(dá)式是常量時性能更好)
- 更簡潔直觀的語法
- 不需要轉(zhuǎn)義反斜杠(
\)
2. 構(gòu)造函數(shù)語法
基本語法
const regex = new RegExp('pattern', 'flags');
或
const regex = new RegExp(/pattern/, 'flags');
特點
- 在運(yùn)行時編譯正則表達(dá)式
- 可以使用變量動態(tài)構(gòu)建正則表達(dá)式
- 字符串中的反斜杠需要轉(zhuǎn)義(
\\) - 可以基于已有的正則對象創(chuàng)建新的正則
何時使用哪種方式
使用字面量語法:
正則模式是固定的、已知的
不需要動態(tài)構(gòu)建正則
需要更好的可讀性
使用構(gòu)造函數(shù)語法:
- 需要動態(tài)構(gòu)建正則表達(dá)式(如基于用戶輸入)
動態(tài)構(gòu)建
在程序運(yùn)行時(而非編寫代碼時)根據(jù)需要創(chuàng)建或修改正則表達(dá)式模式。
- 正則模式需要從變量或配置中獲取
- 需要在運(yùn)行時組合多個正則片段
2. 常用修飾符(flags)
1.i(ignoreCase) - 不區(qū)分大小寫
作用:使匹配不區(qū)分大小寫
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) - 多行模式
作用:使 ^ 和 $ 匹配每行的開頭和結(jié)尾,而不是整個字符串的開頭和結(jié)尾
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 模式
作用:使 . 匹配包括換行符在內(nèi)的任意字符
const textWithNewline = 'Hello\nWorld'; // 不使用 s 修飾符 console.log(/Hello.World/.test(textWithNewline)); // false (.不匹配換行符) // 使用 s 修飾符 console.log(/Hello.World/s.test(textWithNewline)); // true // 替代方案(不使用s修飾符) console.log(/Hello[\s\S]World/.test(textWithNewline)); // true
組合使用多個修飾符
可以同時使用多個修飾符,順序無關(guān)緊要:
// 不區(qū)分大小寫 + 全局匹配 + 多行模式 const regex = /^hello/gim; const text = `Hello world hello everyone HELLO there`; console.log(text.match(regex)); // ["Hello", "hello", "HELLO"]
二、正則表達(dá)式語法詳解
1. 字符匹配
| 模式 | 描述 |
|---|---|
. | 匹配除換行符外的任意字符 |
\d | 匹配數(shù)字,等價于 [0-9] |
\D | 匹配非數(shù)字,等價于 [^0-9] |
\w | 匹配字母、數(shù)字或下劃線 |
\W | 匹配非字母、數(shù)字、下劃線 |
\s | 匹配空白字符(空格、制表符等) |
\S | 匹配非空白字符 |
2. 量詞
| 模式 | 描述 |
|---|---|
* | 匹配前一個表達(dá)式 0 次或多次 |
+ | 匹配前一個表達(dá)式 1 次或多次 |
? | 匹配前一個表達(dá)式 0 次或 1 次 |
{n} | 匹配前一個表達(dá)式恰好 n 次 |
{n,} | 匹配前一個表達(dá)式至少 n 次 |
{n,m} | 匹配前一個表達(dá)式 n 到 m 次 |
3. 位置匹配
| 模式 | 描述 |
|---|---|
^ | 匹配輸入的開始。如,^abc 表示字符串必須以 abc 開頭。 |
$ | 匹配輸入的結(jié)束。如,abc$ 表示字符串必須以 abc 結(jié)尾。 |
\b | 匹配單詞邊界 |
\B | 匹配非單詞邊界 |
4.字符類
| 模式 | 描述 |
|---|---|
[] | 定義一個字符類,匹配方括號內(nèi)的任意一個字符。例如,[abc] 可以匹配 a、b 或 c。 |
[^] | 表示取反,匹配不在方括號內(nèi)的任意一個字符。例如,[^abc] 可以匹配除 a、b、c 之外的任意字符。 |
[a-z]、[A-Z]、[0-9] 等 | 表示范圍,分別匹配小寫字母、大寫字母和數(shù)字。 |
三、TypeScript 中的正則方法
1. RegExp 方法
const regex = /hello/;
// test() - 測試是否匹配
regex.test('hello world'); // true
// exec() - 執(zhí)行搜索,返回匹配結(jié)果或 null
const result = regex.exec('hello world');
console.log(result?.[0]); // "hello"
2. String 方法
const str = 'Hello world, hello TypeScript'; // match() - 返回匹配結(jié)果 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"]
四、實際應(yīng)用示例
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.\.- 匹配點號
- 轉(zhuǎn)義的點號,匹配實際的
.字符 - 域名必須包含一個點號
正則表達(dá)式中的點號.
- 在正則中,未轉(zhuǎn)義的點號
.是一個特殊字符 - 它表示匹配除換行符外的任意單個字符
- 例如
a.c可以匹配 “abc”、“a c”、“a$c” 等
轉(zhuǎn)義點號\.
- 當(dāng)我們需要匹配實際的點號字符時,必須轉(zhuǎn)義它
- 使用反斜杠
\進(jìn)行轉(zhuǎn)義:\. - 這樣
\.就表示字面的點號字符 “.” 而不是通配符
6.[^\s@]+- 頂級域名(TLD)
- 匹配點號后的部分
- 例如在
example.com中匹配com
7.$- 匹配字符串結(jié)束
確保匹配直到字符串結(jié)束,防止后面有其他字符
完整匹配流程
以郵箱 username@example.com 為例:
^從字符串開始[^\s@]+匹配username@匹配@[^\s@]+匹配example\.匹配.[^\s@]+匹配com$確保字符串結(jié)束
2. 提取URL中的參數(shù)
function getUrlParams(url: string): Record<string, string> {
const params: Record<string, string> = {};
const paramRegex = /[?&]([^=#]+)=([^&#]*)/g;
let match;
while ((match = paramRegex.exec(url)) !== null) {
params[match[1]] = match[2];
}
return params;
}
正則表達(dá)式解析
核心的正則表達(dá)式是 /[?&]([^=#]+)=([^&#]*)/g,讓我們分解它的每個部分:
1.[?&]
- 匹配
?或&字符 ?開始查詢參數(shù)部分&分隔多個參數(shù)
2.([^=#]+)
- 第一個捕獲組
(),匹配參數(shù)名 [^=#]匹配任何不是=或#的字符+表示匹配一個或多個這樣的字符
3.=
- 匹配字面的等號,分隔參數(shù)名和值
4.([^&#]*)
- 第二個捕獲組
(),匹配參數(shù)值 [^&#]匹配任何不是&或#的字符*表示匹配零個或多個這樣的字符(允許空值)
5./g
- 全局標(biāo)志,匹配所有符合條件的結(jié)果
匹配過程示例
對于 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”
- 匹配
- 遇到
#停止匹配
執(zhí)行流程
- 初始化空對象
params存儲結(jié)果 - 使用
while循環(huán)和regex.exec()遍歷所有匹配 - 每次匹配:
match[1]是參數(shù)名match[2]是參數(shù)值- 將鍵值對存入
params對象
- 返回最終的
params對象
3. 密碼強(qiáng)度驗證
function checkPasswordStrength(password: string): 'weak' | 'medium' | 'strong' {
// 至少8個字符
if (password.length < 8) return 'weak';
// 弱: 只有字母或數(shù)字
if (/^[a-zA-Z]+$/.test(password) || /^\d+$/.test(password)) {
return 'weak';
}
// 中: 包含字母和數(shù)字
if (/^(?=.*[a-zA-Z])(?=.*\d).+$/.test(password)) {
// 強(qiáng): 包含字母、數(shù)字和特殊字符
if (/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).+$/.test(password)) {
return 'strong';
}
return 'medium';
}
return 'weak';
}
1. 檢查純字母或純數(shù)字
/^[a-zA-Z]+$/ // 純字母 /^\d+$/ // 純數(shù)字
^和$確保整個字符串匹配[a-zA-Z]匹配任何大小寫字母\d匹配數(shù)字+表示一個或多個
2. 檢查同時包含字母和數(shù)字
/^(?=.*[a-zA-Z])(?=.*\d).+$/
(?=.*[a-zA-Z])正向先行斷言,確保字符串包含字母(?=.*\d)正向先行斷言,確保字符串包含數(shù)字
正向先行斷言(?=.*)
基本語法
(?=pattern) 是正向先行斷言的基本形式,表示:
- 當(dāng)前位置后面必須能匹配
pattern - 但匹配后,正則引擎的當(dāng)前位置不會改變
(?=.*[a-zA-Z])(?=.*\d)解析
這個表達(dá)式由兩個正向先行斷言組成,分別檢查密碼中是否包含字母和數(shù)字。
第一個斷言 (?=.*[a-zA-Z])
.*:
.匹配任意字符(除換行符)*表示零次或多次.*組合表示"任意數(shù)量的任意字符"
[a-zA-Z]:
- 匹配任意大小寫字母
- 整體含義:
- 在字符串的任意位置(因為
.*)后面必須有一個字母 - 相當(dāng)于"字符串中必須包含至少一個字母"
第二個斷言 (?=.*\d)
\d:
- 匹配任意數(shù)字(等價于
[0-9])
- 整體含義:
- 在字符串的任意位置后面必須有一個數(shù)字
- 相當(dāng)于"字符串中必須包含至少一個數(shù)字"
組合效果
/^(?=.*[a-zA-Z])(?=.*\d).+$/ 表示:
^從字符串開頭開始(?=.*[a-zA-Z])斷言:后面某處必須有一個字母(?=.*\d)斷言:后面某處必須有一個數(shù)字.+實際匹配:一個或多個任意字符$直到字符串結(jié)束
.+匹配整個字符串(至少一個字符)
3. 檢查包含特殊字符
/^(?=.*[a-zA-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).+$/
(?=.*[^a-zA-Z\d])正向先行斷言,確保字符串包含非字母非數(shù)字的字符(即特殊字符)[^a-zA-Z\d]匹配任何不是字母也不是數(shù)字的字符
總結(jié)
到此這篇關(guān)于TypeScript中正則表達(dá)式的用法及實際應(yīng)用的文章就介紹到這了,更多相關(guān)TS中正則表達(dá)式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript設(shè)計模式之模板方法模式原理與用法示例
這篇文章主要介紹了JavaScript設(shè)計模式之模板方法模式原理與用法,結(jié)合實例形式分析了JavaScript模板方法模式的概念、組成、定義、使用等相關(guān)操作技巧與注意事項,需要的朋友可以參考下2018-08-08
javascript動態(tài)創(chuàng)建表格及添加數(shù)據(jù)實例詳解
這篇文章主要介紹了javascript動態(tài)創(chuàng)建表格及添加數(shù)據(jù),以實例形式分析了javascript動態(tài)創(chuàng)建表格的常用方法,包括不兼容IE6與兼容IE6的實現(xiàn)方法,非常具有實用價值,需要的朋友可以參考下2015-05-05
javascript字符串對象常用api函數(shù)小結(jié)(連接,替換,分割,轉(zhuǎn)換等)
這篇文章主要介紹了javascript字符串對象常用api函數(shù),結(jié)合實例形式總結(jié)分析了javascript常用的連接、替換、分割、轉(zhuǎn)換等相關(guān)函數(shù)與使用方法,需要的朋友可以參考下2016-09-09
js實現(xiàn)瀑布流觸底動態(tài)加載數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)瀑布流觸底動態(tài)加載數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
js實現(xiàn)div拖動動畫運(yùn)行軌跡效果代碼分享
這篇文章主要介紹了js實現(xiàn)div拖動動畫運(yùn)行軌跡效果,推薦給大家,有需要的小伙伴可以參考下。2015-08-08
javascript版的in_array函數(shù)(判斷數(shù)組中是否存在特定值)
這篇文章主要介紹了javascript版的in_array函數(shù)(判斷數(shù)組中是否存在特定值),需要的朋友可以參考下2014-05-05

