在JavaScript的正则表达式使用场景中,我们常常需要通过分组提取匹配到的内容,但有时也需要获取分组未匹配到的部分字符串。比如一段文本中标记了特定格式的内容,需要把匹配到的部分和未匹配的部分分别处理,这时候就需要掌握分组匹配未匹配内容的实现方法。

正则表达式分组基础回顾
正则表达式中的分组通过小括号(和)实现,默认情况下分组会捕获匹配到的内容,我们可以通过RegExp.exec或者字符串的match方法获取分组捕获的结果。例如下面的代码,我们匹配日期中的年、月、日分组:
const str = '2024-05-20';
const reg = /(d{4})-(d{2})-(d{2})/;
const result = reg.exec(str);
console.log(result[1]); // 输出 2024,第一个分组匹配的年
console.log(result[2]); // 输出 05,第二个分组匹配的月
console.log(result[3]); // 输出 20,第三个分组匹配的日
通过索引位置计算未匹配内容
正则匹配结果中会返回匹配到的内容在整个字符串中的起始和结束索引,我们可以通过这些索引切割原字符串,得到分组未匹配的内容。匹配结果的索引信息如下:
index:匹配内容在原字符串中的起始位置result[0].length:匹配到的完整内容的长度,起始位置加长度就是匹配内容的结束位置
下面的示例演示如何获取分组匹配内容前后的未匹配部分:
const text = '开头内容[需要提取的部分]结尾内容';
const reg = /[(.*?)]/; // 分组匹配中括号内的内容
const matchResult = reg.exec(text);
if (matchResult) {
const matchStart = matchResult.index; // 匹配起始位置
const matchEnd = matchStart + matchResult[0].length; // 匹配结束位置
const beforeMatch = text.slice(0, matchStart); // 匹配前的未匹配内容
const afterMatch = text.slice(matchEnd); // 匹配后的未匹配内容
const matchedGroup = matchResult[1]; // 分组匹配到的内容
console.log('匹配前的未匹配内容:', beforeMatch); // 输出 开头内容
console.log('分组匹配的内容:', matchedGroup); // 输出 需要提取的部分
console.log('匹配后的未匹配内容:', afterMatch); // 输出 结尾内容
}
通过反向匹配逻辑获取未匹配内容
如果我们需要获取不符合分组匹配规则的内容,可以使用正则表达式的否定匹配或者正向/反向断言来实现。比如我们需要把字符串中所有不是数字分组匹配的内容提取出来,可以结合match方法和全局匹配模式:
const str = 'a1b2c3d4';
const numReg = /d/; // 匹配单个数字的分组规则
// 先获取所有匹配到的数字分组内容
const matchedNums = str.match(/d/g);
console.log('匹配到的数字分组内容:', matchedNums); // 输出 ['1','2','3','4']
// 通过替换的方式获取未匹配的内容
const notMatched = str.replace(/d/g, '');
console.log('未匹配的内容:', notMatched); // 输出 abcd
如果是更复杂的分组规则,也可以使用类似的思路,先匹配到所有符合分组规则的内容,再把原字符串中这些内容去掉,剩下的就是未匹配的内容。
两种方案的选择建议
如果只需要获取单次匹配中分组前后的未匹配内容,优先选择索引计算的方式,性能更高且逻辑直观。如果需要处理全局匹配场景,或者要获取所有不符合分组规则的内容,反向匹配或者替换的方式会更合适。需要注意的是,使用全局匹配时exec方法需要循环调用才能获取所有匹配结果,而match方法在全局模式下不会返回分组捕获的内容,要根据实际需求选择方法。
JavaScript正则表达式分组匹配未匹配内容修改时间:2026-06-10 13:06:15