JS正則表達式介紹(JavaScript正則表達式)

文章目錄

  • JavaScript正則表達式完全指南
    • 正則表達式基礎
    • 元字符與特殊字符
      • 基本元字符
        • `.` - 點號
        • `\d` - 數字
        • `\D` - 非數字
        • `\w` - 單詞字符
        • `\W` - 非單詞字符
        • `\s` - 空白字符
        • `\S` - 非空白字符
    • 正則表達式標志
      • 常用標志詳解
        • `g` - 全局匹配
        • `i` - 忽略大小寫
        • `m` - 多行匹配
        • `s` - 點號匹配所有字符
        • `u` - Unicode模式
        • `y` - 粘性匹配
      • 組合使用標志
      • 在RegExp構造函數中使用標志
      • 通過屬性檢查標志
    • 量詞與邊界
      • 量詞
        • `*` - 零次或多次
        • `+` - 一次或多次
        • `?` - 零次或一次
        • `{n}` - 恰好n次
        • `{n,}` - 至少n次
        • `{n,m}` - n到m次
      • 邊界匹配
        • `^` - 行首
        • `$` - 行尾
        • `\b` - 單詞邊界
        • `\B` - 非單詞邊界
    • 分組與捕獲
      • 基本分組
      • 命名捕獲組
    • 斷言與零寬斷言
        • `(?=...)` - 正向前瞻
        • `(?!...)` - 負向前瞻
        • `(?<=...)` - 正向后顧
        • `(?<!...)` - 負向后顧
    • JavaScript中的正則表達式方法
      • String對象的方法
        • `search()` - 查找匹配
        • `replace()` - 替換匹配
        • `split()` - 分割字符串
        • `match()` - 獲取匹配
        • `matchAll()` - 獲取所有匹配信息
      • RegExp對象的方法
        • `test()` - 測試匹配
        • `exec()` - 執行匹配
    • 高級應用與技巧
      • 貪婪與非貪婪匹配
        • 貪婪匹配
        • 非貪婪匹配
      • 常見應用場景
        • 驗證電子郵箱
        • 驗證手機號
        • 提取URL參數
    • 性能優化
      • 避免回溯過多
      • 使用非捕獲組
    • 總結

JavaScript正則表達式完全指南

正則表達式基礎

正則表達式是一種強大的文本處理工具,用于匹配、搜索和替換文本中的特定模式。在JavaScript中,正則表達式是一種對象,可以通過字面量或構造函數創建。

// 使用字面量創建正則表達式
const pattern1 = /hello/;
// 這里創建了一個匹配"hello"字符串的正則表達式// 使用構造函數創建正則表達式
const pattern2 = new RegExp("hello");
// 這種方法也創建了一個匹配"hello"的正則表達式,效果與上面相同

元字符與特殊字符

正則表達式的強大之處在于其元字符系統,這些特殊字符具有特殊含義。

基本元字符

. - 點號

匹配除換行符外的任意單個字符

// 使用點號匹配任意字符
const dotPattern = /h.t/g;
"hit hot hat h t".match(dotPattern); // 結果: ["hit", "hot", "hat"]
// 解釋: 點號匹配除換行符外的任意字符,所以匹配到"hit", "hot", "hat",但不匹配"h t"
\d - 數字

匹配任何數字字符(0-9)

// 匹配任意數字
const digitPattern = /\d/g;
"abc123".match(digitPattern); // 結果: ["1", "2", "3"]
// 解釋: \d匹配任意單個數字,g標志表示全局匹配,所以找到了所有數字
\D - 非數字

匹配任何非數字字符

// 匹配任意非數字字符
const nonDigitPattern = /\D/g;
"abc123".match(nonDigitPattern); // 結果: ["a", "b", "c"]
// 解釋: \D匹配任意非數字字符,所以匹配到了字母a、b和c
\w - 單詞字符

匹配字母、數字、下劃線

// 匹配單詞字符
const wordCharPattern = /\w/g;
"a1_!".match(wordCharPattern); // 結果: ["a", "1", "_"]
// 解釋: \w匹配字母、數字和下劃線,所以匹配到a、1和_,但不匹配!
\W - 非單詞字符

匹配非字母、數字、下劃線的字符

// 匹配非單詞字符
const nonWordCharPattern = /\W/g;
"a1_!".match(nonWordCharPattern); // 結果: ["!"]
// 解釋: \W匹配非字母、數字、下劃線的字符,所以只匹配到!
\s - 空白字符

匹配空格、制表符、換行符等空白字符

// 匹配空白字符
const whitespacePattern = /\s/g;
"a b\tc\nd".match(whitespacePattern); // 結果: [" ", "\t", "\n"]
// 解釋: \s匹配任意空白字符,所以匹配到空格、制表符和換行符
\S - 非空白字符

匹配任何非空白字符

// 匹配所有非空白字符
const nonWhitespacePattern = /\S/g;
"hello world".match(nonWhitespacePattern); // 結果: ["h","e","l","l","o","w","o","r","l","d"]
// 解釋: \S匹配任意非空白字符,這里匹配了所有字母,空格被排除

正則表達式標志

正則表達式末尾的字母是"標志"(flags),用于控制正則表達式的匹配行為。這些標志放在正則表達式的結束斜杠/之后。

// 格式: /pattern/flags
const regex = /hello/g;  // g是全局匹配標志
// 這個正則表達式會匹配所有出現的"hello",而不僅僅是第一個

常用標志詳解

g - 全局匹配

啟用全局搜索,查找所有匹配項而不是只找第一個

// 不帶g標志 - 只匹配第一個結果
"hello hello".match(/hello/); // 結果: ["hello"]
// 解釋: 沒有g標志,所以只返回第一個匹配的"hello"// 帶g標志 - 匹配所有結果
"hello hello".match(/hello/g); // 結果: ["hello", "hello"]
// 解釋: 有g標志,所以返回所有匹配的"hello",這里有兩個
i - 忽略大小寫

進行不區分大小寫的匹配

// 不帶i標志 - 區分大小寫
"Hello".match(/hello/); // 結果: null
// 解釋: 默認區分大小寫,所以"Hello"與"hello"不匹配,返回null// 帶i標志 - 忽略大小寫
"Hello".match(/hello/i); // 結果: ["Hello"]
// 解釋: i標志使匹配不區分大小寫,所以"Hello"與"hello"匹配成功
m - 多行匹配

允許^和$匹配每一行的開始和結束

const multiline = "line1\nline2\nline3";// 不帶m標志 - ^和$只匹配整個字符串的開始和結束
multiline.match(/^line/g); // 結果: ["line"]
// 解釋: 沒有m標志,^只匹配整個字符串的開始,所以只匹配到第一行的"line"// 帶m標志 - ^和$匹配每一行的開始和結束
multiline.match(/^line/gm); // 結果: ["line", "line", "line"]
// 解釋: 有m標志,^匹配每一行的開始,所以匹配到所有三行開頭的"line"
s - 點號匹配所有字符

讓點號(.)匹配包括換行符在內的所有字符

const text = "line1\nline2";// 不帶s標志 - 點號不匹配換行符
text.match(/line1.line2/); // 結果: null
// 解釋: 沒有s標志,.不匹配換行符\n,所以模式不匹配// 帶s標志 - 點號匹配包括換行符在內的所有字符
text.match(/line1.line2/s); // 結果: ["line1\nline2"]
// 解釋: 有s標志,.可以匹配換行符\n,所以整個模式匹配成功
u - Unicode模式

啟用完整的Unicode支持

// 啟用Unicode屬性轉義
/\p{Script=Greek}/u.test('π'); // 結果: true
// 解釋: u標志啟用Unicode支持,允許使用\p{...}匹配特定Unicode屬性,這里匹配希臘文字符// 正確處理Unicode代理對
"𠮷".match(/./u)[0].length; // 結果: 1 (正確識別為單個字符)
// 解釋: u標志使得正則表達式正確處理占用兩個代碼單元的Unicode字符,如"𠮷",識別為一個字符
y - 粘性匹配

僅從正則表達式的lastIndex屬性開始匹配

const str = "first second";
const sticky = /\w+/y;
sticky.lastIndex = 6; // 設置開始搜索位置為6(即"second"的開始位置)
sticky.test(str); // 結果: true,匹配"second"
// 解釋: y標志使正則表達式只從指定的lastIndex位置開始匹配,匹配到了"second"// 如果設置位置不是單詞開頭,則不匹配
sticky.lastIndex = 7; // 設置到"econd"
sticky.test(str); // 結果: false
// 解釋: lastIndex設為7,不是單詞開頭,y標志要求必須從lastIndex位置精確匹配,所以匹配失敗

組合使用標志

標志可以組合使用,實現更靈活的匹配行為:

// 全局匹配 + 忽略大小寫
"Hello hello HELLO".match(/hello/gi); // 結果: ["Hello", "hello", "HELLO"]
// 解釋: g標志使匹配全局化,i標志使匹配不區分大小寫,所以找到所有大小寫形式的"hello"// 全局匹配 + 多行匹配
const text = "Line1\nLine2\nLine3";
text.match(/^Line\d$/gm); // 結果: ["Line1", "Line2", "Line3"]
// 解釋: g標志使匹配全局化,m標志使^和$分別匹配每行的開始和結束,
// \d匹配一個數字,所以匹配到每行的完整內容

在RegExp構造函數中使用標志

// 使用字符串第二參數指定標志
const regex1 = new RegExp("pattern", "gi");
// 解釋: 創建一個正則表達式匹配"pattern",帶有g(全局)和i(忽略大小寫)標志// 從現有正則復制并添加新標志
const originalRegex = /pattern/g;
const newRegex = new RegExp(originalRegex, "i"); // 結果: /pattern/gi
// 解釋: 從已有的帶g標志的正則表達式創建新的正則表達式,并添加i標志

通過屬性檢查標志

const regex = /test/gi;regex.global; // true (是否有g標志)
regex.ignoreCase; // true (是否有i標志)
regex.multiline; // false (是否有m標志)
regex.dotAll; // false (是否有s標志)
regex.unicode; // false (是否有u標志)
regex.sticky; // false (是否有y標志)
// 解釋: 通過正則表達式對象的屬性可以檢查該正則表達式是否設置了特定標志

量詞與邊界

量詞

* - 零次或多次

匹配前一項0次或多次

// 使用*匹配0次或多次
const starPattern = /ab*c/g;
"ac abc abbc".match(starPattern); // 結果: ["ac", "abc", "abbc"]
// 解釋: b*匹配0個或多個b,所以匹配到"ac"(0個b)、"abc"(1個b)和"abbc"(2個b)
+ - 一次或多次

匹配前一項1次或多次

// 使用+匹配1次或多次
const plusPattern = /ab+c/g;
"ac abc abbc".match(plusPattern); // 結果: ["abc", "abbc"]
// 解釋: b+匹配1個或多個b,所以匹配到"abc"和"abbc",但不匹配"ac"(沒有b)
? - 零次或一次

匹配前一項0次或1次

// 使用?匹配0次或1次
const questionPattern = /ab?c/g;
"ac abc abbc".match(questionPattern); // 結果: ["ac", "abc"]
// 解釋: b?匹配0個或1個b,所以匹配到"ac"和"abc",但不匹配"abbc"(有2個b)
{n} - 恰好n次

匹配前一項恰好n次

// 使用{n}匹配恰好n次
const exactPattern = /ab{2}c/g;
"abc abbc abbbc".match(exactPattern); // 結果: ["abbc"]
// 解釋: b{2}匹配恰好2個b,所以只匹配到"abbc"
{n,} - 至少n次

匹配前一項至少n次

// 使用{n,}匹配至少n次
const atLeastPattern = /ab{2,}c/g;
"abc abbc abbbc".match(atLeastPattern); // 結果: ["abbc", "abbbc"]
// 解釋: b{2,}匹配至少2個b,所以匹配到"abbc"(2個b)和"abbbc"(3個b)
{n,m} - n到m次

匹配前一項至少n次,最多m次

// 使用{n,m}匹配n到m次
const rangePattern = /ab{1,2}c/g;
"abc abbc abbbc".match(rangePattern); // 結果: ["abc", "abbc"]
// 解釋: b{1,2}匹配1到2個b,所以匹配到"abc"(1個b)和"abbc"(2個b),但不匹配"abbbc"(3個b)

邊界匹配

^ - 行首

匹配輸入的開始位置,在多行模式下匹配每一行的開始

// 使用^匹配行首
const startPattern = /^start/;
"start line\nanother line".match(startPattern); // 結果: ["start"]
// 解釋: ^匹配字符串開頭,所以匹配到開頭的"start"// 在多行模式下
const multilineStartPattern = /^line/gm;
"first line\nline two".match(multilineStartPattern); // 結果: ["line"]
// 解釋: 在多行模式下,^匹配每行的開頭,所以匹配到第二行開頭的"line"
$ - 行尾

匹配輸入的結束位置,在多行模式下匹配每一行的結束

// 使用$匹配行尾
const endPattern = /end$/;
"line end\nline".match(endPattern); // 結果: ["end"]
// 解釋: $匹配字符串結尾,所以匹配到第一行結尾的"end"// 在多行模式下
const multilineEndPattern = /line$/gm;
"first line\nline two".match(multilineEndPattern); // 結果: ["line"]
// 解釋: 在多行模式下,$匹配每行的結尾,所以匹配到第一行結尾的"line"
\b - 單詞邊界

匹配單詞邊界,即字母與非字母之間的位置

// 匹配以字母a開頭的單詞
const startsWithA = /\ba\w*/g;
"apple banana grape avocado".match(startsWithA); // 結果: ["apple", "avocado"]
// 解釋: \b匹配單詞邊界,a匹配字母a,\w*匹配零個或多個字母、數字或下劃線,
// 所以匹配以a開頭的單詞"apple"和"avocado"
\B - 非單詞邊界

匹配非單詞邊界

// 匹配不在單詞邊界的'a'
const nonBoundaryA = /\Ba\w*/g;
"apple banana grape avocado".match(nonBoundaryA); // 結果: ["ana"]
// 解釋: \B匹配非單詞邊界,a匹配字母a,\w*匹配零個或多個字母、數字或下劃線,
// 所以匹配到"banana"中的"ana",因為這個'a'不在單詞開頭

分組與捕獲

基本分組

使用圓括號()可以將正則表達式的一部分組合起來,作為一個單元。

// 匹配重復的單詞
const repeatedWord = /(\w+)\s+\1/g;
"hello hello world".match(repeatedWord); // 結果: ["hello hello"]
// 解釋: 
// (\w+) - 捕獲組,匹配一個或多個單詞字符(字母、數字或下劃線)
// \s+ - 匹配一個或多個空白字符
// \1 - 反向引用,引用第一個捕獲組匹配的內容
// 整體匹配連續重復的單詞,如"hello hello"// 捕獲組的使用
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2023-05-15".match(datePattern);
// match[0]: "2023-05-15" (完整匹配)
// match[1]: "2023" (第一個捕獲組 - 年份)
// match[2]: "05" (第二個捕獲組 - 月份)
// match[3]: "15" (第三個捕獲組 - 日期)
// 解釋: 每個括號內的內容形成一個捕獲組,匹配結果中可以通過索引訪問每個捕獲組

命名捕獲組

ES2018引入了命名捕獲組,使得訪問捕獲的內容更加直觀。

// 使用命名捕獲組解析日期
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = "2023-05-15".match(datePattern);
// match.groups.year: "2023"
// match.groups.month: "05"
// match.groups.day: "15"
// 解釋: 
// (?<year>\d{4}) - 命名為"year"的捕獲組,匹配四位數字
// (?<month>\d{2}) - 命名為"month"的捕獲組,匹配兩位數字
// (?<day>\d{2}) - 命名為"day"的捕獲組,匹配兩位數字
// 通過match.groups對象可以按名稱訪問捕獲的內容,更加直觀

斷言與零寬斷言

斷言不消耗字符,只進行位置匹配。

(?=...) - 正向前瞻

匹配后面跟著特定模式的位置

// 前瞻斷言:匹配后面跟著"張"的所有字符
const lookAheadPattern = /\w+(?=張)/g;
"李明張三王五".match(lookAheadPattern); // 結果: ["李明"]
// 解釋: \w+匹配一個或多個字符,(?=張)是一個前瞻斷言,表示后面必須跟著"張"
// 所以匹配到"李明",因為它后面是"張"
(?!...) - 負向前瞻

匹配后面不跟著特定模式的位置

// 負前瞻:匹配后面不是數字的字母序列
const negativeLookAhead = /[a-z]+(?!\d)/g;
"abc1 def2 ghi".match(negativeLookAhead); // 結果: ["ab", "de", "ghi"]
// 解釋: [a-z]+匹配一個或多個小寫字母,(?!\d)是一個負前瞻斷言,表示后面不能是數字
// 所以匹配到"abc1"中的"ab"(c后面是數字1),"def2"中的"de"(f后面是數字2),
// 以及"ghi"(后面沒有任何字符)
(?<=...) - 正向后顧

匹配前面有特定模式的位置

// 后顧斷言:匹配前面是數字的字母
const lookBehindPattern = /(?<=\d)[a-z]+/g;
"1apple 2banana 3grape".match(lookBehindPattern); // 結果: ["apple", "banana", "grape"]
// 解釋: (?<=\d)是一個后顧斷言,表示前面必須有一個數字
// [a-z]+匹配一個或多個小寫字母
// 所以匹配到跟在數字后面的字母序列:"apple"、"banana"和"grape"
(?<!...) - 負向后顧

匹配前面沒有特定模式的位置

// 負后顧斷言:匹配前面不是數字的字母
const negativeLookBehindPattern = /(?<!\d)[a-z]+/g;
"1apple word 2banana".match(negativeLookBehindPattern); // 結果: ["word"]
// 解釋: (?<!\d)是一個負后顧斷言,表示前面不能是數字
// [a-z]+匹配一個或多個小寫字母
// 所以只匹配到"word",因為它前面不是數字

JavaScript中的正則表達式方法

String對象的方法

search() - 查找匹配

查找字符串中是否存在匹配,返回首次匹配的位置索引,如果沒有匹配則返回-1

const str = "JavaScript正則表達式很強大";
const pattern = /正則表達式/;// 測試是否包含模式
str.search(pattern); // 返回首次匹配的索引: 10
// 解釋: search方法返回第一個匹配的位置索引,這里"正則表達式"從索引10開始
replace() - 替換匹配

將匹配的文本替換為指定內容

const str = "JavaScript正則表達式很強大";
const pattern = /正則表達式/;// 替換匹配內容
str.replace(pattern, "RegExp"); // 結果: "JavaScriptRegExp很強大"
// 解釋: replace方法將匹配的"正則表達式"替換為"RegExp"
split() - 分割字符串

使用正則表達式匹配的內容作為分隔符來分割字符串

// 分割字符串
"apple,banana,orange".split(/,/); // 結果: ["apple", "banana", "orange"]
// 解釋: split方法根據正則表達式匹配的內容(這里是逗號)分割字符串
match() - 獲取匹配

獲取字符串中匹配正則表達式的部分

const str = "JavaScript正則表達式很強大";// 匹配所有結果
const matches = str.match(/\w+/g); // 結果: ["JavaScript"]
// 解釋: match方法返回匹配的結果,\w+匹配一個或多個字母、數字或下劃線字符
// 這里只匹配到拉丁字符部分"JavaScript",因為\w默認不匹配中文字符
matchAll() - 獲取所有匹配信息

返回一個包含所有匹配結果的迭代器

const str = "test1 test2 test3";
const regexp = /test(\d)/g;
const matches = [...str.matchAll(regexp)];// matches[0]: ["test1", "1"] (第一次匹配及其捕獲組)
// matches[1]: ["test2", "2"] (第二次匹配及其捕獲組)
// matches[2]: ["test3", "3"] (第三次匹配及其捕獲組)
// 解釋: matchAll返回所有匹配的信息,包括每次匹配的完整字符串和捕獲組

RegExp對象的方法

test() - 測試匹配

測試字符串是否匹配正則表達式模式,返回布爾值

const pattern = /Java(Script)/;
const str = "JavaScript是一種腳本語言";// 測試是否匹配
pattern.test(str); // 結果: true
// 解釋: test方法檢查字符串是否匹配正則表達式,返回布爾值
exec() - 執行匹配

在字符串中執行匹配搜索,返回詳細的匹配信息

const pattern = /Java(Script)/;
const str = "JavaScript是一種腳本語言";// 獲取匹配信息
const execResult = pattern.exec(str);
// execResult[0]: "JavaScript" (完整匹配)
// execResult[1]: "Script" (第一個捕獲組)
// execResult.index: 0 (匹配位置)
// 解釋: exec方法返回一個數組,包含匹配的完整字符串和所有捕獲組,
// 以及匹配的位置信息(index屬性)

高級應用與技巧

貪婪與非貪婪匹配

貪婪匹配

默認情況下,正則表達式的量詞是貪婪的,會盡可能多地匹配字符

const text = "<div>內容1</div><div>內容2</div>";// 貪婪匹配 - 匹配盡可能長的字符串
const greedyPattern = /<div>.*<\/div>/;
text.match(greedyPattern)[0]; // 結果: "<div>內容1</div><div>內容2</div>"
// 解釋: .*是貪婪匹配,會匹配盡可能多的字符,所以匹配了整個字符串從第一個<div>到最后一個</div>
非貪婪匹配

在量詞后添加?使其變為非貪婪匹配,會盡可能少地匹配字符

const text = "<div>內容1</div><div>內容2</div>";// 非貪婪匹配 - 匹配盡可能短的字符串
const nonGreedyPattern = /<div>.*?<\/div>/g;
text.match(nonGreedyPattern); // 結果: ["<div>內容1</div>", "<div>內容2</div>"]
// 解釋: .*?是非貪婪匹配,會匹配盡可能少的字符,加上g標志匹配所有可能的結果,
// 所以分別匹配到了兩個完整的div標簽內容

常見應用場景

驗證電子郵箱

使用正則表達式驗證電子郵件地址格式

// 驗證電子郵箱
const emailPattern = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
emailPattern.test("test@example.com"); // 結果: true
// 解釋: 
// ^[\w-]+ - 以一個或多個字母、數字、下劃線或連字符開始
// (\.[\w-]+)* - 可能跟著點號和更多字符(如user.name)
// @ - 然后是@符號
// ([\w-]+\.)+ - 一個或多個由點號分隔的域名部分
// [a-zA-Z]{2,7}$ - 以2-7個字母的頂級域名結束
驗證手機號

驗證中國大陸手機號格式

// 驗證中國手機號
const phonePattern = /^1[3-9]\d{9}$/;
phonePattern.test("13812345678"); // 結果: true
// 解釋:
// ^1 - 以數字1開頭
// [3-9] - 第二位是3到9之間的數字
// \d{9}$ - 后面跟著9個數字結束
// 此正則匹配中國大陸常見的11位手機號碼
提取URL參數

從URL中提取查詢參數

// 提取URL參數
function getUrlParams(url) {const pattern = /[?&]([^=&#]+)=([^&#]*)/g;const params = {};let match;while ((match = pattern.exec(url)) !== null) {// match[1]: 參數名// match[2]: 參數值params[match[1]] = decodeURIComponent(match[2]);}return params;
}// 示例
const url = "https://example.com/search?query=正則表達式&lang=zh&page=1";
const params = getUrlParams(url);
// 結果: {query: "正則表達式", lang: "zh", page: "1"}
// 解釋:
// [?&] - 匹配問號或&符號(URL參數的開始)
// ([^=&#]+) - 第一個捕獲組匹配參數名(不包含=、&、#的字符序列)
// = - 匹配等號
// ([^&#]*) - 第二個捕獲組匹配參數值(不包含&、#的字符序列)
// 循環使用exec方法獲取所有參數,并構建參數對象

性能優化

避免回溯過多

避免使用可能導致災難性回溯的模式

// 避免回溯過多
// 不良示例 - 可能導致災難性回溯
const badPattern = /^(\w+)+$/;
// 解釋: 這種嵌套量詞的模式((\w+)+)可能導致指數級回溯,
// 對于某些輸入可能引起正則表達式引擎長時間計算甚至崩潰// 改進版本
const betterPattern = /^\w+$/;
// 解釋: 簡化版本,僅匹配一個或多個單詞字符,沒有嵌套量詞,性能更好

使用非捕獲組

當不需要引用捕獲內容時,使用非捕獲組提高性能

// 避免使用不必要的捕獲組
// 不良示例
const capturePattern = /(\d+)-(\d+)-(\d+)/;
// 解釋: 如果不需要使用捕獲的內容,這些捕獲組會消耗額外的內存和處理時間// 非捕獲組版本 - 如果不需要使用捕獲的內容
const nonCapturePattern = /(?:\d+)-(?:\d+)-(?:\d+)/;
// 解釋: 使用非捕獲組(?:...)代替捕獲組(),如果不需要引用匹配的內容,
// 這樣可以提高性能,特別是在大型文本處理中

總結

JavaScript正則表達式是一種強大的文本處理工具,掌握其基本語法和高級技巧可以大幅提高文本處理效率。正則表達式由元字符、量詞、分組等組成,通過合理組合這些元素,能夠實現復雜的模式匹配需求。正確理解和使用標志(flags)可以讓正則表達式匹配更精確、更高效,適應不同的文本處理需求。在實際應用中,需要注意正則表達式的可讀性和性能問題,避免過于復雜的模式導致難以維護或性能下降。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80501.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80501.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80501.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Kubernetes 使用 containerd 實現 GPU 支持及 GPU Operator 部署指南

目錄 Kubernetes 使用 containerd 實現 GPU 支持及 GPU Operator 部署指南 一、為什么 containerd 是趨勢&#xff1f; 二、目標 三、前提條件 四、方式一&#xff1a;containerd nvidia-container-toolkit&#xff08;基礎方式&#xff09; 1?? 安裝 NVIDIA Containe…

leetcode 2918. 數組的最小相等和 中等

給你兩個由正整數和 0 組成的數組 nums1 和 nums2 。 你必須將兩個數組中的 所有 0 替換為 嚴格 正整數&#xff0c;并且滿足兩個數組中所有元素的和 相等 。 返回 最小 相等和 &#xff0c;如果無法使兩數組相等&#xff0c;則返回 -1 。 示例 1&#xff1a; 輸入&#xf…

猿人學第十二題-js入門

1. 鏈接 https://match.yuanrenxue.cn/match/12 2. 抓包分析 2.1. m參數 通過觀察&#xff0c;只有m參數要解決&#xff1a; 3. 逆向分析 3.1. 跟棧 直接跟棧吧&#xff0c;一下就出結果了&#xff1a; 可以看到m其實很簡單&#xff0c;就是固定字符串 當前頁數&#xf…

雙系統電腦中如何把ubuntu裝進外接移動固態硬盤

電腦&#xff1a;win11 ubuntu22.04 實體機 虛擬機&#xff1a;VMware17 鏡像文件&#xff1a;ubuntu-22.04.4-desktop-amd64.iso 或者 ubuntu20.4的鏡像 外接固態硬盤1個 一、首先win11中安裝vmware17 具體安裝方法&#xff0c;網上很多教程 二、磁盤分區 1.在筆…

202535| Kafka架構與重要概念+冪等性+事務

好的&#xff01;以下是關于 Kafka 架構 以及其 重要概念 的詳細介紹&#xff0c;結合 Mermaid 圖形 和 表格&#xff0c;幫助你更好地理解各個概念的關系和作用。 Kafka 架構與重要概念 Kafka 是一個分布式消息系統&#xff0c;廣泛應用于日志收集、流處理、事件驅動架構等場…

從0開始學習大模型--Day05--理解prompt工程

提示詞工程原理 N-gram&#xff1a;通過統計&#xff0c;計算N個詞共同出現的概率&#xff0c;從而預測下一個詞是什么。 深度學習模型&#xff1a;有多層神經網絡組成&#xff0c;可以自動從數據中學習特征&#xff0c;讓模型通過不斷地自我學習不斷成長&#xff0c;直到模型…

Amazing晶焱科技:系統級 EOS 測試方法 - System Level EOS Testing Method

系統上常見的EOS測試端口以AC電源、電話線&#xff08;RJ11&#xff09;、同軸電纜&#xff08;coaxial cable&#xff09;以及以太網絡&#xff08;RJ45&#xff09;最常見&#xff0c;這些端口因有機會布線至戶外的關系&#xff0c;受到EOS/Surge沖擊的幾率也大大提升。因此電…

數據結構—(概述)

目錄 一 數據結構&#xff0c;相關概念 1. 數據結構&#xff1a; 2. 數據(Data): 3. 數據元素(Data Element): 4. 數據項&#xff1a; 5. 數據對象(Data Object): 6. 容器&#xff08;container&#xff09;&#xff1a; 7. 結點&#xff08;Node&#xff09;&#xff…

Vue 兩種導航方式

目錄 一、聲明式導航 二、編程式導航 三、兩句話總結 一、聲明式導航 1. 傳參跳轉&#xff1a; <router-link :to"/user?nameCHEEMS&id114514">Query傳參 </router-link><router-link :to"/user?參數名1參數值1&參數名2參數值2&a…

QTableWidget實現多級表頭、表頭凍結效果

最終效果&#xff1a; 實現思路&#xff1a;如果只用一個表格的話寫起來比較麻煩&#xff0c;可以考慮使用兩個QTableWidget組合&#xff0c;把復雜的表頭一個用QTableWidget顯示&#xff0c;其他內容用另一個QTableWidget。 #include "mainwindow.h" #include &qu…

2025年客運從業資格證備考單選練習題

客運從業資格證備考單選練習題 1、從事道路旅客運輸活動時&#xff0c;應當采取必要措施保證旅客的人身和財產安全&#xff0c;發生緊急情況時&#xff0c;首先應&#xff08; &#xff09;。 A. 搶救財產 B. 搶救傷員 C. 向公司匯報 答案&#xff1a;B 解析&#xff1a;…

python打卡day21

常見的降維算法 知識點回顧&#xff1a; LDA線性判別PCA主成分分析t-sne降維 之前學了特征降維的兩個思路&#xff0c;特征篩選&#xff08;如樹模型重要性、方差篩選&#xff09;和特征組合&#xff08;如SVD/PCA&#xff09;。 現在引入特征降維的另一種分類&#xff1a;無/有…

專業級軟件卸載工具:免費使用,徹底卸載無殘留!

在數字生活節奏日益加快的今天&#xff0c;我們的電腦就像每天都在"吃進"各種軟件。但您是否注意到&#xff0c;那些看似消失的程序其實悄悄留下了大量冗余文件&#xff1f;就像廚房角落里積攢的調味瓶空罐&#xff0c;日積月累就會讓系統變得"消化不良"。…

【Linux】基礎 IO(一)

&#x1f4dd;前言&#xff1a; 這篇文章我們來講講Linux——基礎IO主要包括&#xff1a; 文件基本概念回顧 C文件的操作介紹系統關于文件的基本操作 &#x1f3ac;個人簡介&#xff1a;努力學習ing &#x1f4cb;個人專欄&#xff1a;Linux &#x1f380;CSDN主頁 愚潤求學 …

Java 原生實現代碼沙箱之Java 程序安全控制(OJ判題系統第2期)——設計思路、實現步驟、代碼實現

在看這一期之前&#xff0c;需要先看上一期的文章&#xff1a; Java 原生實現代碼沙箱&#xff08;OJ判題系統第1期&#xff09;——設計思路、實現步驟、代碼實現-CSDN博客 Java 程序可能出現的異常情況 1、執行超時 占用時間資源&#xff0c;導致程序卡死&#xff0c;不釋…

常見的降維算法

作業&#xff1a; 自由作業&#xff1a;探索下什么時候用到降維&#xff1f;降維的主要應用&#xff1f;或者讓ai給你出題&#xff0c;群里的同學互相學習下。可以考慮對比下在某些特定數據集上t-sne的可視化和pca可視化的區別。 一、什么時候用到降維&#xff1f; 降維通常…

理解Yocto項目中`${D}`作為模擬目標系統根文件結構的臨時目錄

在Yocto項目中,理解${D}作為模擬目標系統根文件結構的臨時目錄,可以通過以下具象化的比喻和結構解析來把握其核心邏輯: 一、沙盒模型:構建系統的“實驗場地” ${D}的作用類似于建筑師在施工前搭建的1:1實體模型。它完全模仿目標設備的文件系統布局(如/usr/bin、/etc等目錄…

第十課認識約數

課堂學習&#xff1a; 情景引入&#xff1a; 今天我們來認識一下數學中的約數關系&#xff0c;上節課我們了解完倍數之后就已經對約數有了基本的概念&#xff01; 我們按照是否有余數&#xff0c;可以把他們分成兩類 在整數除法中&#xff0c;如果商是整數沒有余數&#x…

【Vue】vuex的getters mapState mapGetters mapMutations mapActions的使用

目錄 一、getters 二、 mapState 三、 mapGetters 四、 mapMutations 五、 mapActions 學到這兒來個小總結&#xff1a;四個map方法的使用 總結不易~ 本章節對我有很大的收獲&#xff0c; 希望對你也是&#xff01;&#xff01;&#xff01; 本節素材已上傳至Gitee&…

html object標簽介紹(用于嵌入外部資源通用標簽)(已不推薦使用deprecated,建議使用img、video、audio標簽)

文章目錄 HTML <object> 標簽詳解基本語法與核心屬性關鍵屬性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同類型的資源1. **嵌入圖像**2. **嵌入音頻**3. **嵌入視頻**4. **嵌入 PDF** 參數傳遞與回退內容**參數&#xff08;<param>&a…