字符串截取大法:JavaScript 中的 6 种高效技巧,90% 开发者都不知道第 5 种!

252 阅读3分钟

一、基础方法:substring、substr 和 slice

1. substring() 方法

substring() 是最传统的字符串截取方法,它接受两个参数:起始索引和结束索引(可选)。

const str = "Hello, JavaScript!";

// 从索引7开始截取到末尾
console.log(str.substring(7)); // "JavaScript!"

// 从索引7截取到17(不包括17)
console.log(str.substring(7, 17)); // "JavaScript"

// 有趣特性:会自动交换参数如果start>end
console.log(str.substring(5, 3)); // "lo" (等同于 substring(3,5))
console.log(str.substring(3, 5)); // "lo"

特点

  • 不修改原字符串
  • 负参数会被当作0
  • 自动处理起始大于结束的情况

2. substr() 方法(已废弃)

虽然 substr() 仍然可用,但已被标记为遗留功能,不建议在新代码中使用。

const str = "Hello, JavaScript!";

// 从索引7开始截取10个字符
console.log(str.substr(7, 10)); // "JavaScript"

特点

  • 第二个参数是长度而非结束索引
  • 负的起始索引表示从末尾开始计算

3. slice() 方法

slice() 是最推荐的通用截取方法,行为与数组的 slice() 一致。

const str = "Hello, JavaScript!";

// 从索引7截取到末尾
console.log(str.slice(7)); // "JavaScript!"

// 从索引7截取到17(不包括17)
console.log(str.slice(7, 17)); // "JavaScript"

// 支持负索引(从末尾计算)
console.log(str.slice(-6)); // "cript!"
console.log(str.slice(7, -1)); // "JavaScript"

特点

  • 支持负索引
  • 不自动交换参数
  • 更直观和一致的行为

二、高级技巧:正则表达式截取

4. match() 方法

当需要基于模式而非位置截取时,正则表达式是强大工具。

const str = "订单号:ORD-2023-98765,请查收";

// 提取订单号
const orderNumber = str.match(/ORD-\d{4}-\d{5}/)[0];
console.log(orderNumber); // "ORD-2023-98765"

// 提取所有数字
const numbers = str.match(/\d+/g);
console.log(numbers); // ["2023", "98765"]

高级用法

  • 使用捕获组提取特定部分
  • 全局匹配获取所有符合项

5. split() + 解构赋值

这个组合技巧能优雅地提取字符串的特定部分。

const fullName = "张 三";

// 传统方式
const parts = fullName.split(" ");
const firstName = parts[0];
const lastName = parts[1];

// 使用解构赋值
const [firstName, lastName] = fullName.split(" ");
console.log(firstName, lastName); // "张" "三"

// 处理URL路径
const url = "/products/electronics/12345";
const [,, category, id] = url.split("/");
console.log(category, id); // "electronics" "12345"

优势

  • 代码简洁
  • 可读性强
  • 一次性提取多个部分

三、ES6+ 现代方法

6. 国际化截取:Intl.Segmenter

处理像中文、日文等没有空格分隔的语言时,传统方法难以正确截取词语。

const str = '测试字符串,包含中文和英文。';

// 传统方法会按字截取s
console.log(str.slice(0, 4)); // "测试字符" (可能不准确)

// 使用Intl.Segmenter按词截取
const segmenter = new Intl.Segmenter('zh-CN', { granularity: 'word' });
const segments = [...segmenter.segment(str)];
const firstWord = segments[0].segment;
console.log(firstWord); // "测试" (完整词)
console.log(segments.map((seg) => seg.segment)); // ['测试', '字符','串',   ',','包含', '中文','和',   '英文','。']

优势

  • 尊重语言规则
  • 正确处理象形文字、表情符号等
  • 支持多种粒度(字、词、句子)

四、性能优化与最佳实践

  1. 性能比较

    • 对于简单截取,slice() 通常性能最好
    • 复杂模式匹配时,预编译正则表达式更高效
  2. 安全截取

    function safeSlice(str, maxLength, suffix = "...") {
      if (str.length <= maxLength) return str;
      return str.slice(0, maxLength - suffix.length) + suffix;
    }
    
    console.log(safeSlice("这是一个很长的字符串", 8)); // "这是一个..."
    
  3. 多字节字符处理

    function mbSubstr(str, start, length) {
      return [...str].slice(start, start + length).join("");
    }
    
    console.log(mbSubstr("👨👩👧👦家庭", 1, 2)); // "👩👧"
    

结语

如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript开发干货。