JavaScript 正则表达式

发布于:2025-06-17 ⋅ 阅读:(10) ⋅ 点赞:(0)

JavaScript 正则表达式(Regular Expression)是用于匹配字符串模式的强大工具。以下是关于 JavaScript 正则表达式的详细介绍:

基本语法

正则表达式使用斜杠 / 包围模式,或通过 RegExp 构造函数创建:

// 字面量语法
const regex1 = /pattern/flags;

// 构造函数语法
const regex2 = new RegExp('pattern', 'flags');

常用标志(flags)

  • g:全局匹配(查找所有匹配项)。
  • i:忽略大小写。
  • m:多行匹配。
  • s:允许 . 匹配换行符。
  • u:启用 Unicode 模式。
  • y:粘性匹配(从上次匹配位置开始)。

常用元字符和模式

1. 字符类
  • .:匹配除换行符外的任意字符。
  • \d:匹配数字(等价于 [0-9])。
  • \D:匹配非数字(等价于 [^0-9])。
  • \w:匹配单词字符(字母、数字、下划线,等价于 [a-zA-Z0-9_])。
  • \W:匹配非单词字符。
  • \s:匹配空白字符(空格、制表符、换行符等)。
  • \S:匹配非空白字符。
2. 量词
  • *:匹配前面的元素 0 次或多次。
  • +:匹配前面的元素 1 次或多次。
  • ?:匹配前面的元素 0 次或 1 次(可选)。
  • {n}:匹配前面的元素恰好 n 次。
  • {n,}:匹配前面的元素至少 n 次。
  • {n,m}:匹配前面的元素至少 n 次,最多 m 次。
3. 定位符
  • ^:匹配字符串的开头(多行模式下匹配行首)。
  • $:匹配字符串的结尾(多行模式下匹配行尾)。
  • \b:匹配单词边界。
  • \B:匹配非单词边界。
4. 分组和引用
  • (...):捕获组,将匹配的部分存储在内存中。
  • (?:...):非捕获组,仅用于分组不存储结果。
  • \1\2, ...:反向引用,引用前面捕获组的内容。
5. 或操作符
  • |:匹配多个模式之一,例如 cat|dog 匹配 "cat" 或 "dog"。

字符串方法与正则结合

  1. test():检查字符串是否匹配模式,返回 true 或 false

    const regex = /apple/i;
    console.log(regex.test("I like Apples")); // true
    
  2. exec():返回匹配结果的数组,或 null

    const regex = /\d+/g;
    console.log(regex.exec("Hello 123 World 456")); // ["123"]
    
  3. match():返回匹配结果的数组,或 null

    const str = "Hello 123 World 456";
    console.log(str.match(/\d+/g)); // ["123", "456"]
    
  4. replace():替换匹配的字符串。

    const str = "Hello World";
    console.log(str.replace(/World/, "Doubao")); // "Hello Doubao"
    
  5. split():根据正则表达式分割字符串。

    const str = "Hello,World!How are you?";
    console.log(str.split(/[^\w]+/)); // ["Hello", "World", "How", "are", "you"]
    

示例:验证邮箱格式

const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

console.log(emailRegex.test("test@example.com")); // true
console.log(emailRegex.test("invalid.email@.com")); // false

注意事项

  1. 转义字符:在正则中使用特殊字符(如 .\() 等)需要转义,例如 \. 匹配点号。
  2. 贪婪与非贪婪匹配
    • 贪婪匹配(默认):尽可能多地匹配,例如 /a+/ 对 "aaab" 匹配 "aaa"
    • 非贪婪匹配:在量词后加 ?,例如 /a+?/ 对 "aaab" 匹配 "a"
  3. 性能考虑:复杂的正则表达式可能导致性能问题,尤其是包含回溯的模式。

如果需要具体场景的正则表达式实现,可以提供更多细节!

1.在JavaScript中,如何使用正则表达式进行字符串替换?

在 JavaScript 中,可以使用 String.prototype.replace() 方法结合正则表达式(RegExp)来实现灵活的字符串替换。以下是详细介绍和示例:

基本语法

const newString = originalString.replace(regexp, replacement);
  • regexp:正则表达式对象(或直接传入正则字面量)。
  • replacement:替换文本(可以是字符串或函数)。

常见用法示例

1. 全局替换(使用 g 标志)
const str = "Hello World! Hello Doubao!";
const newStr = str.replace(/Hello/g, "Hi");
console.log(newStr); // "Hi World! Hi Doubao!"
2. 忽略大小写(使用 i 标志)
const str = "Apple is red. apple is sweet.";
const newStr = str.replace(/apple/gi, "Orange");
console.log(newStr); // "Orange is red. Orange is sweet."
3. 使用捕获组(分组替换)

捕获组通过 () 定义,可以在替换文本中用 $1$2 等引用。

// 交换姓和名的位置
const name = "Zhang San";
const newName = name.replace(/(\w+)\s(\w+)/, "$2, $1");
console.log(newName); // "San, Zhang"
4. 使用函数动态生成替换文本
const str = "Today is 2023-06-16";
const newStr = str.replace(/(\d{4})-(\d{2})-(\d{2})/, (match, year, month, day) => {
  return `${month}/${day}/${year}`;
});
console.log(newStr); // "Today is 06/16/2023"
5. 特殊字符替换(如换行符)
const text = "Line 1\nLine 2";
const newText = text.replace(/\n/g, "<br>");
console.log(newText); // "Line 1<br>Line 2"

替换文本中的特殊变量

在替换字符串中,可以使用以下特殊变量:

  • $1$2, ...:引用第 n 个捕获组的内容。
  • $&:引用整个匹配的文本。
  • `$``:匹配文本之前的部分。
  • $':匹配文本之后的部分。
  • $$:插入一个美元符号 $

示例:

const str = "Hello world";
const newStr = str.replace(/world/, "[$&]");
console.log(newStr); // "Hello [world]"

进阶技巧

1. 替换 HTML 标签内容
const html = "<p>Hello <b>Doubao</b></p>";
const newHtml = html.replace(/<b>(.*?)<\/b>/g, "<strong>$1</strong>");
console.log(newHtml); // "<p>Hello <strong>Doubao</strong></p>"
2. 驼峰命名转连字符(kebab-case)
const camelCase = "userName";
const kebabCase = camelCase.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
console.log(kebabCase); // "user-name"
3. 安全转义 HTML 特殊字符
const unsafe = 'Hello <script>alert("XSS");</script>';
const safe = unsafe.replace(/[<>"&]/g, (char) => {
  const entities = {
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    '&': '&amp;'
  };
  return entities[char] || char;
});
console.log(safe); // "Hello &lt;script&gt;alert(\"XSS\");&lt;/script&gt;"

注意事项

  1. 仅替换首个匹配项:如果正则表达式没有 g 标志,replace() 只会替换第一个匹配项。

    const str = "one two three";
    const newStr = str.replace(/\w+/, "NUM");
    console.log(newStr); // "NUM two three"
    
  2. 正则表达式中的特殊字符:需要转义特殊字符(如 .\^ 等)。

    const str = "Hello.world";
    const newStr = str.replace(/\./, "-"); // 注意转义 .
    console.log(newStr); // "Hello-world"
    
  3. 使用 replaceAll() 方法(ES2021+):

    const str = "aabbcc";
    const newStr = str.replaceAll("b", "-"); // 无需正则
    console.log(newStr); // "aa--cc"
    

常见应用场景

  • 格式化日期、电话号码等字符串。
  • 转义 / 过滤用户输入(如防止 XSS 攻击)。
  • 模板引擎中的变量替换。
  • 文本处理(如 Markdown 转 HTML)。

2.如何使用正则表达式进行字符串分割?

如何使用正则表达式进行字符串分割?

在 JavaScript 中,可以使用 String.prototype.split() 方法结合正则表达式(RegExp)来实现灵活的字符串分割。以下是详细介绍和示例:

基本语法

const array = originalString.split(regexp, limit);
  • regexp:用于匹配分隔符的正则表达式。
  • limit(可选):限制返回数组的最大长度。

常见用法示例

1. 按多个分隔符分割

使用 | 操作符定义多个分隔符:

const str = "Hello,world!How are you?";
const words = str.split(/[,\s!?.]+/);
console.log(words); // ["Hello", "world", "How", "are", "you"]
2. 保留分隔符(使用捕获组)

将分隔符放入括号 () 中,分隔符会被保留在结果数组中:

const str = "2023-06-16";
const parts = str.split(/-/);
console.log(parts); // ["2023", "06", "16"]

// 保留分隔符
const partsWithDelimiters = str.split(/(-)/);
console.log(partsWithDelimiters); // ["2023", "-", "06", "-", "16"]
3. 按单词边界分割

使用 \b 匹配单词边界:

const text = "HelloWorld123";
const parts = text.split(/\b/);
console.log(parts); // ["Hello", "World", "123"]
4. 忽略空字符串(过滤结果)
const str = "a,,b,c,,";
const filtered = str.split(/,+/).filter(Boolean);
console.log(filtered); // ["a", "b", "c"]
5. 按行分割(处理不同换行符)
const text = "Line 1\nLine 2\r\nLine 3\rLine 4";
const lines = text.split(/\r\n|\r|\n/);
console.log(lines); // ["Line 1", "Line 2", "Line 3", "Line 4"]

进阶技巧

1. 按复杂模式分割(如 HTML 标签)
const html = "<div>Hello</div><span>World</span>";
const tags = html.split(/(<[^>]+>)/).filter(Boolean);
console.log(tags); // ["<div>", "Hello", "</div>", "<span>", "World", "</span>"]
2. 按重复字符序列分割
const str = "aaa---bbb===ccc";
const parts = str.split(/[-=]+/);
console.log(parts); // ["aaa", "bbb", "ccc"]
3. 按模式出现次数分割

例如,每 3 个字符分割一次:

const str = "abcdefghij";
const chunks = str.match(/.{1,3}/g) || [];
console.log(chunks); // ["abc", "def", "ghi", "j"]

注意事项

  1. 空字符串的处理

    • 如果字符串以分隔符开头或结尾,split() 会在结果数组的开头或结尾添加空字符串。
    const str = ",a,b,";
    console.log(str.split(/,/)); // ["", "a", "b", ""]
    
  2. 正则表达式中的特殊字符
    需要转义特殊字符(如 .|[ 等):

    const str = "a.b.c";
    const parts = str.split(/\./); // 注意转义 .
    console.log(parts); // ["a", "b", "c"]
    
  3. 性能考虑
    复杂的正则表达式可能影响性能,尤其是处理大量文本时。

常见应用场景

  • 解析 CSV 文件(按逗号分割)。
  • 处理多行文本(按换行符分割)。
  • 格式化字符串(如按固定长度分割)。
  • 解析 URL 参数(按 & 和 = 分割)。

3.在使用正则表达式进行字符串分割时,如何避免空字符串的出现?

在使用正则表达式进行字符串分割时,空字符串通常出现在原字符串的开头、结尾或连续分隔符之间。以下是几种避免空字符串的方法:

1. 使用 filter(Boolean) 过滤结果

这是最直接的方法,通过 filter 过滤掉所有 “假值”(包括空字符串 "")。

const str = ",a,,b,";
const parts = str.split(/,+/).filter(Boolean);
console.log(parts); // ["a", "b"]

2. 使用正则表达式排除空匹配

通过前瞻断言(lookahead)确保分隔符后有内容:

const str = ",a,,b,";
const parts = str.split(/,(?=.)/); // 匹配后面有字符的逗号
console.log(parts); // ["a", "b"]

3. 处理开头和结尾的分隔符

使用 trim() 去除字符串首尾的分隔符:

const str = ",a,,b,";
const parts = str.trim(',').split(/,+/); // 先去除首尾逗号
console.log(parts); // ["a", "b"]

4. 自定义过滤函数

更精确地控制过滤逻辑:

const str = ",a,,b,";
const parts = str.split(/,+/).filter((part) => part.length > 0);
console.log(parts); // ["a", "b"]

5. 结合捕获组保留分隔符(需特殊处理)

如果使用捕获组保留分隔符,空字符串可能来自分隔符本身,需调整过滤逻辑:

const str = "a--b---c";
const parts = str.split(/(-+)/).filter((part, index) => {
  // 保留非空内容或分隔符
  return part.length > 0 || (index % 2 === 1);
});
console.log(parts); // ["a", "--", "b", "---", "c"]

示例对比

方法 输入 ",a,,b," 输出
split(/,+/).filter() ",a,,b," ["a", "b"]
trim().split(/,+/) ",a,,b," ["a", "b"]
split(/,(?=.)/) ",a,,b," ["a", "b"]

注意事项

  • 性能filter 会创建新数组,大数据量时需注意。
  • 分隔符位置:前瞻断言 (?=...) 不消耗字符,适用于分隔符后必须有内容的场景。
  • 复杂场景:若分隔符本身有意义(如保留分隔符),需自定义过滤逻辑。


网站公告

今日签到

点亮在社区的每一天
去签到