JS正则表达式:使用方法与实例
JavaScript正则表达式(Regular Expression,简称regex或regexp)是一种强大、灵活且高效的文本处理工具,用于匹配、查找、替换字符串中的特定模式。掌握正则表达式是前端开发中处理用户输入、数据验证、文本解析等任务的关键技能。
一、什么是正则表达式?
正则表达式是由一系列特殊字符和普通字符组成的字符串,它定义了一种模式,用于在文本中搜索和操作匹配该模式的字符串。
二、创建正则表达式
在JavaScript中,创建正则表达式有两种方式:
-
字面量方式 (Literal Notation)
这是最常用和推荐的方式,在脚本加载时编译。
javascript
const regex1 = /pattern/flags; -
构造函数方式 (Constructor Function)
当正则表达式的模式是动态生成时使用。在运行时编译。
javascript
const regex2 = new RegExp('pattern', 'flags');
flags (标志):用于指定匹配模式的选项。
g(global): 全局匹配,查找所有匹配而非找到第一个就停止。i(case-insensitive): 忽略大小写。m(multiline): 多行匹配,^和$会匹配行首和行尾(不仅仅是整个字符串的开头和结尾)。u(unicode): 启用Unicode支持,正确处理四个字节的Unicode字符。y(sticky): 粘性匹配,只从lastIndex属性指定的位置开始匹配。
示例:
javascript
const re1 = /hello/i; // 匹配 "hello" 或 "Hello" 等,不区分大小写
const re2 = new RegExp('world', 'g'); // 全局匹配 "world"
三、正则表达式的常见方法
JavaScript的 RegExp 对象和 String 对象都提供了与正则表达式交互的方法。
A. RegExp 对象的方法
-
test()
检查字符串是否包含与正则表达式匹配的模式。返回true或false。
javascript
const regex = /cat/;
console.log(regex.test("The cat sat on the mat.")); // true
console.log(regex.test("The dog barked.")); // false -
exec()
在字符串中执行匹配搜索。如果找到匹配,返回一个包含匹配信息(匹配的子字符串、捕获组等)的数组,并更新正则表达式对象的lastIndex属性(如果设置了g标志)。如果没有找到匹配,返回null。
“`javascript
const regex = /quick (brown).*(jumps)/g;
const str = “The quick brown fox jumps over the lazy dog.”;
let match;while ((match = regex.exec(str)) !== null) {
console.log(Found "${match[0]}" at index ${match.index}. Next search starts at ${regex.lastIndex}.);
console.log(Captured groups: ${match[1]}, ${match[2]});
}
// Output:
// Found “quick brown fox jumps” at index 4. Next search starts at 23.
// Captured groups: brown, jumps
“`
B. String 对象的方法
-
match()
使用正则表达式在字符串中查找匹配项。- 如果正则表达式没有
g标志,返回一个数组,包含第一个匹配项、捕获组及索引等信息(类似于exec())。 - 如果正则表达式有
g标志,返回一个包含所有匹配子字符串的数组,但不会返回捕获组信息。如果没有匹配,返回null。
“`javascript
const str = “Is this all there is?”;
const regex1 = /is/;
const regex2 = /is/g;
console.log(str.match(regex1));
// Output: [“is”, index: 2, input: “Is this all there is?”, groups: undefined]console.log(str.match(regex2));
// Output: [“is”, “is”]console.log(“No match”.match(/xyz/)); // null
“` - 如果正则表达式没有
-
search()
查找与正则表达式匹配的第一个子字符串的索引。如果没有匹配,返回-1。
javascript
const str = "The quick brown fox.";
console.log(str.search(/brown/)); // 10
console.log(str.search(/cat/)); // -1 -
replace()
使用替换字符串或替换函数替换与正则表达式匹配的子字符串。- 如果正则表达式没有
g标志,只替换第一个匹配项。 - 如果正则表达式有
g标志,替换所有匹配项。
“`javascript
const str = “apple, banana, apple, orange.”;
console.log(str.replace(/apple/, “grape”)); // “grape, banana, apple, orange.” (只替换第一个)
console.log(str.replace(/apple/g, “grape”)); // “grape, banana, grape, orange.” (替换所有)
// 使用函数作为替换参数
const s = “bar foo baz”;
console.log(s.replace(/(\w+)/g, (match, p1) => p1.toUpperCase())); // “BAR FOO BAZ”
“` - 如果正则表达式没有
-
split()
使用正则表达式或固定字符串作为分隔符,将字符串分割成子字符串数组。
javascript
const str = "apple,banana;orange.grape";
console.log(str.split(/[,;.]/)); // ["apple", "banana", "orange", "grape"]
四、正则表达式的元字符和特殊序列
正则表达式的强大之处在于其使用的元字符,它们具有特殊的含义。
A. 字符类
.: 匹配除换行符以外的任何单个字符。[xyz]: 匹配x、y或z中的任何一个字符。[^xyz]: 匹配除x、y或z以外的任何字符。[a-z]: 匹配a到z范围内的任何小写字母。[A-Z]: 匹配A到Z范围内的任何大写字母。[0-9]: 匹配0到9范围内的任何数字。[a-zA-Z0-9_]: 匹配任何字母、数字或下划线。
B. 预定义字符类(简写)
\d: 匹配任何数字字符 (等同于[0-9])。\D: 匹配任何非数字字符 (等同于[^0-9])。\w: 匹配任何单词字符 (字母、数字或下划线,等同于[a-zA-Z0-9_])。\W: 匹配任何非单词字符 (等同于[^a-zA-Z0-9_])。\s: 匹配任何空白字符 (空格、制表符、换页符等)。\S: 匹配任何非空白字符。
C. 量词
用于指定匹配字符或组出现的次数。
*: 匹配前一个表达式0次或多次 (等同于{0,})。+: 匹配前一个表达式1次或多次 (等同于{1,})。?: 匹配前一个表达式0次或1次 (等同于{0,1})。{n}: 匹配前一个表达式恰好n次。{n,}: 匹配前一个表达式至少n次。{n,m}: 匹配前一个表达式至少n次,但不超过m次。
贪婪与非贪婪匹配:
默认情况下,量词是“贪婪的”,会尽可能多地匹配字符。在量词后面加上 ? 可以使其变为“非贪婪的”,尽可能少地匹配字符。
*?: 匹配0次或多次,非贪婪。+?: 匹配1次或多次,非贪婪。??: 匹配0次或1次,非贪婪。{n,}?: 至少n次,非贪婪。
示例:
javascript
const html = "<div><span>hello</span><span>world</span></div>";
console.log(html.match(/<span>.*<\/span>/)); // 贪婪匹配:["<span>hello</span><span>world</span>"]
console.log(html.match(/<span>.*?<\/span>/g)); // 非贪婪匹配:["<span>hello</span>", "<span>world</span>"]
D. 定位符
用于指定匹配发生的位置。
^: 匹配字符串的开头 (如果设置m标志,匹配行首)。$: 匹配字符串的结尾 (如果设置m标志,匹配行尾)。\b: 匹配单词边界。\B: 匹配非单词边界。
示例:
javascript
console.log(/^hello/.test("hello world")); // true
console.log(/world$/.test("hello world")); // true
console.log(/\bcat\b/.test("The cat sat.")); // true
console.log(/\bcat\b/.test("category")); // false (cat不是一个独立的单词)
E. 分组和捕获
(pattern): 捕获组。将pattern匹配到的内容捕获起来,可以在结果数组中通过索引访问。(?:pattern): 非捕获组。只分组,不捕获匹配内容,不占用捕获组的索引。|: 或运算符。匹配|左右两边的任意一个模式 (如cat|dog匹配 “cat” 或 “dog”)。
示例:
“`javascript
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const dateStr = “Today is 2023-10-26.”;
const match = dateStr.match(dateRegex);
if (match) {
console.log(“Full match:”, match[0]); // “2023-10-26”
console.log(“Year:”, match[1]); // “2023”
console.log(“Month:”, match[2]); // “10”
console.log(“Day:”, match[3]); // “26”
}
“`
五、常用实例
1. 验证邮箱地址
“`javascript
function isValidEmail(email) {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/;
return emailRegex.test(email);
}
console.log(isValidEmail(“[email protected]”)); // true
console.log(isValidEmail(“invalid-email”)); // false
“`
2. 验证手机号码 (中国大陆简单示例)
“`javascript
function isValidPhoneNumber(phone) {
// 匹配1开头的11位数字 (更严格的验证需要考虑运营商号段)
const phoneRegex = /^1[3-9]\d{9}$/;
return phoneRegex.test(phone);
}
console.log(isValidPhoneNumber(“13812345678”)); // true
console.log(isValidPhoneNumber(“12345678901”)); // false (非1开头)
“`
3. 从URL中提取参数
“`javascript
function getQueryParams(url) {
const params = {};
const queryRegex = /?&=([^&]*)/g;
let match;
while ((match = queryRegex.exec(url)) !== null) {
params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
return params;
}
const url = “https://example.com/search?q=javascript&page=2&sort=asc”;
console.log(getQueryParams(url));
// Output: { q: “javascript”, page: “2”, sort: “asc” }
“`
4. 去除字符串首尾空格
javascript
const strWithSpaces = " Hello World ";
console.log(strWithSpaces.replace(/^\s+|\s+$/g, "")); // "Hello World"
// 现代JS更推荐使用 trim() 方法
console.log(strWithSpaces.trim()); // "Hello World"
5. 格式化数字,每三位加逗号
“`javascript
function formatNumberWithCommas(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, “,”);
}
console.log(formatNumberWithCommas(123456789)); // “123,456,789”
console.log(formatNumberWithCommas(1234.56)); // “1,234.56”
“`
六、总结
JavaScript正则表达式是一个非常强大的工具,理解其语法和常用方法能极大地提高文本处理的效率和代码的健壮性。虽然初学时可能觉得复杂,但通过不断练习和查阅文档,你会发现它在日常开发中的巨大价值。记住,在线正则表达式测试工具(如 regex101.com, regexr.com)是学习和调试正则表达式的好帮手。