JavaScript substring:按索引提取文本

JavaScript substring 方法会提取两个索引位置之间的字符并返回新字符串。它接收起始索引和可选的结束索引(不包含),会从 start 提取到 end 之前。省略结束索引时,会一直提取到字符串末尾。与 slice 不同,substring 在 start 大于 end 时会自动交换两个参数,从而避免意外得到空字符串。

JavaScript Substring 文本提取示例

输出:

输出将显示在这里...

输出:

名称: report-2024
扩展名: csv

这个示例如何工作

  1. filename.lastIndexOf(".") 返回 11,也就是字符串中最后一个点号的位置。
  2. filename.substring(0, 11) 从索引 0 提取到(不含)索引 11,得到 "report-2024"
  3. filename.substring(12) 省略了结束参数,因此会从索引 12 一直提取到字符串末尾,返回 "csv"
  4. 两次调用都会返回新字符串,原始的 filename 不会被修改,因为 JavaScript 字符串是不可变的。

JavaScript substring 的常见错误

误以为负索引会从末尾开始计数。

错误写法:

"hello".substring(-3); // "hello",不是 "llo"

正确写法:

"hello".slice(-3); // "llo"

substring 会把负数参数钳制为 0,所以 substring(-3) 会变成 substring(0) 并返回整个字符串。要按末尾偏移提取时请使用 slice

把第二个参数当成长度。

错误写法:

"abcdef".substring(2, 3); // "c",不是 "cde"

正确写法:

"abcdef".substring(2, 5); // "cde"

第二个参数是结束索引,不是字符数量。这类混淆通常来自旧的 substr(start, length),其中 "abcdef".substr(2, 3) 会返回 "cde"。从 substr 迁移时,应把长度转换为结束索引:start + length

JavaScript substring 与 slice 对比

行为substring(start, end)slice(start, end)
负数参数钳制为 0从字符串末尾计数
start > end自动交换参数返回空字符串 ""
索引越界钳制为 string.length钳制为 string.length
是否修改原字符串

当索引来自计算且可能前后顺序颠倒时,使用 substring 更稳妥,自动交换能保证返回有效结果。需要有意使用负偏移时,用 slice,例如 str.slice(-N) 提取最后 N 个字符。

用 substring 替换旧版 substr

旧版 substr(start, length) 方法(常被称为 JavaScript substr)在老代码里仍很常见,并且在文档中已被标记为弃用。JavaScript substr substring 的混淆通常来自第二个参数含义不同:substr 接收长度,而 substring 接收结束索引。安全迁移可按以下步骤进行:

  1. str.substr(start, length) 替换为 str.substring(start, start + length)
  2. 如果 start 可能为负值,请改用 slice(start, start + length),因为 substring 会把负数钳制为 0
  3. 测试 length0、负数或省略时的边界情况,因为 substrsubstring 在这些输入上的行为并不一致。

FAQ

JavaScript substring 和 slice 有什么区别?

两者都能按索引提取字符串片段,但在边界行为上不同。substring 会把负参数钳制为 0,并在 start 大于 end 时交换参数;slice 会把负数当作从末尾计算的偏移,并在 start 大于 end 时返回空字符串。常规的正向索引提取场景下,两者结果一致。

JavaScript substring 会修改原字符串吗?

不会。JavaScript 字符串是不可变的,所有字符串方法都会返回新字符串。调用 substring 后原字符串保持不变。把返回值赋给变量即可保留提取结果。

substring 中 start 大于 end 会发生什么?

substring 会静默交换这两个参数。"abcdef".substring(4, 1) 的行为等同于 "abcdef".substring(1, 4),返回 "bcd"。这种归一化能避免索引计算反转时意外得到空字符串。