为什么在开启多行模式的情况下,\D+仍然会跨行匹配?

前端开发 2026-07-08
let str = `a
b`;

// ✔
for (let match of str.matchAll (/^.+$/mg))
  console.log (match);

// ✔ 
for (let match of str.matchAll (/^[^0-9]$/mg))
  console.log (match);

// ⚠️ problem
for (let match of str.matchAll (/^\D+$/mg))
  console.log (match);

/**
Output:
["a"]
["b"]

["a"]
["b"]

// ⚠️ problem
["a\nb"]
*/

解决方案

这是正常且在预期之内的情况。你遇到了一个贪婪匹配,重复的字符类被允许匹配换行符。下面的正则表达式都能匹配 a\nb

let str = 'a\nb';

console.log(Array.from(str.matchAll(/^.+$/msg)));
console.log(Array.from(str.matchAll(/^[^0-9]+$/mg)));
console.log(Array.from(str.matchAll(/^\D+$/mg)));

如果你不使用dotall标志 /s. 将不会匹配换行符,而会分别匹配 ab

let str = 'a\nb';

console.log(Array.from(str.matchAll(/^.+$/mg)));

如果你使用非贪婪的重复,它将在换行符处停止,对于下面这些,你将得到分离的 ab 匹配:

let str = 'a\nb';

console.log(Array.from(str.matchAll(/^.+?$/msg)));
console.log(Array.from(str.matchAll(/^[^0-9]+?$/mg)));
console.log(Array.from(str.matchAll(/^\D+?$/mg)));

如果你根本不使用重复,字符类只允许匹配单个字符(你的行就是这样的长度),对于下列所有正则表达式,你将得到分离的 ab 匹配:

let str = 'a\nb';

console.log(Array.from(str.matchAll(/^.$/msg)));
console.log(Array.from(str.matchAll(/^[^0-9]$/mg)));
console.log(Array.from(str.matchAll(/^\D$/mg)));
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章