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"。
字符串方法与正则结合
test()
:检查字符串是否匹配模式,返回true
或false
。const regex = /apple/i; console.log(regex.test("I like Apples")); // true
exec()
:返回匹配结果的数组,或null
。const regex = /\d+/g; console.log(regex.exec("Hello 123 World 456")); // ["123"]
match()
:返回匹配结果的数组,或null
。const str = "Hello 123 World 456"; console.log(str.match(/\d+/g)); // ["123", "456"]
replace()
:替换匹配的字符串。const str = "Hello World"; console.log(str.replace(/World/, "Doubao")); // "Hello Doubao"
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
注意事项
- 转义字符:在正则中使用特殊字符(如
.
,\
,(
,)
等)需要转义,例如\.
匹配点号。 - 贪婪与非贪婪匹配:
- 贪婪匹配(默认):尽可能多地匹配,例如
/a+/
对"aaab"
匹配"aaa"
。 - 非贪婪匹配:在量词后加
?
,例如/a+?/
对"aaab"
匹配"a"
。
- 贪婪匹配(默认):尽可能多地匹配,例如
- 性能考虑:复杂的正则表达式可能导致性能问题,尤其是包含回溯的模式。
如果需要具体场景的正则表达式实现,可以提供更多细节!
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 = {
'<': '<',
'>': '>',
'"': '"',
'&': '&'
};
return entities[char] || char;
});
console.log(safe); // "Hello <script>alert(\"XSS\");</script>"
注意事项
仅替换首个匹配项:如果正则表达式没有
g
标志,replace()
只会替换第一个匹配项。const str = "one two three"; const newStr = str.replace(/\w+/, "NUM"); console.log(newStr); // "NUM two three"
正则表达式中的特殊字符:需要转义特殊字符(如
.
,\
,^
等)。const str = "Hello.world"; const newStr = str.replace(/\./, "-"); // 注意转义 . console.log(newStr); // "Hello-world"
使用
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"]
注意事项
空字符串的处理:
- 如果字符串以分隔符开头或结尾,
split()
会在结果数组的开头或结尾添加空字符串。
const str = ",a,b,"; console.log(str.split(/,/)); // ["", "a", "b", ""]
- 如果字符串以分隔符开头或结尾,
正则表达式中的特殊字符:
需要转义特殊字符(如.
,|
,[
等):const str = "a.b.c"; const parts = str.split(/\./); // 注意转义 . console.log(parts); // ["a", "b", "c"]
性能考虑:
复杂的正则表达式可能影响性能,尤其是处理大量文本时。
常见应用场景
- 解析 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
会创建新数组,大数据量时需注意。 - 分隔符位置:前瞻断言
(?=...)
不消耗字符,适用于分隔符后必须有内容的场景。 - 复杂场景:若分隔符本身有意义(如保留分隔符),需自定义过滤逻辑。