出来混迟早要还的-获取字符串中的子串

298 阅读3分钟

先看 Demo

手机号脱敏:185****2278( 保留前三位和后四位, 中间用*处理 )

function maskify(str) {
  return str.substr(0, 3) + "****" + str.substr(7);
  return str.substring(0, 3) + "****" + str.substring(str.length - 4);
  return str.slice(0, 3) + str.slice(-4).padStart(8, "*");
}
console.log(maskify("18500002278"));

三种实现分别使用 substr\substring\slice, 那么三个获取子串的方法有哪些共同点?有哪些差异?

共同点:提供了三种不同获取字符串的思路( 长度、正向确定起止位置、两端确认起止位置 ) substrsubstring 的区别?

  1. 最显著的差异:substr 的第二个参数是长度, 而 substring 是结束位置
  2. substr 第一个参数可以为负数( 从右向左 ), substring 要实现类似的效果需要借助字符串长度减去对应数值

slice 和( substr、substring )什么关系?

  1. slice 像是 substring 的进阶( 起止位置可以使用负数 )

substr

String.prototype.substr()

  1. 返回一个字符串中从指定位置开始到指定长度的字符
  2. 如果忽略 length, substr 提取字符, 直到字符串末尾
  3. 如果为负值, substr 会把它作为从字符串末尾开始的一个字符索引( sourceLength + 负值 )
  4. 如果负值大于字符串长度, substr 会使用 0 作为开始索引
  5. 如果第二个参数为 0负值, substr 会返回一个空字符串
  6. 如果第一个参数大于或等于字符串的长度, substr 返回一个空字符串

substring

String.prototype.substring()

  1. 返回一个字符串开始索引到结束索引( 不包括 )之间的子集, 或从开始索引到字符串末尾的子集
  2. 如果省略参数 2, substring 提取字符串一直到字符串末尾
  3. 如果任一参数小于 0 或为 NaN, 则被当作 0
  4. 如果任一参数大于字符串长度, 则被当作字符串长度( stringName.length )
  5. 如果参数 1 等于参数 2, substring 返回一个空字符串
  6. 如果参数 1 大于参数 2, substring 会调换参数

slice

String.prototype.slice()

slice == ( substring 参数 1 参数 2 可以设置负数 ) + ( 参数 1 大于参数 2 时,不会调换参数 )

// 手机号脱敏的replace方案
function maskify(str) {
  return str.replace(str.substr(3, 4), "****");
  return str.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
}
console.log(maskify("18500002278"));

加深 substr/substring/clice 应用

"Brave New World" 变成了 "Brave New Web"

// substring
function replaceString(olds, news, fulls) {
  let oldsLen = olds.length;
  for (let i = 0; i < fulls.length; i++) {
    if (fulls.substring(i, i + oldsLen) == olds) {
      fulls = fulls.substring(0, i) + news + fulls.substring(i + oldsLen);
      console.log(fulls);
    }
  }
}
replaceString("World", "Web", "Brave New World");

// 拷贝一份把substring修改为slice, 结果一致
function replaceString(olds, news, fulls) {
  let oldsLen = olds.length;
  for (let i = 0; i < fulls.length; i++) {
    if (fulls.slice(i, i + oldsLen) == olds) {
      fulls = fulls.slice(0, i) + news + fulls.slice(i + oldsLen);
      console.log(fulls);
    }
  }
}
replaceString("World", "Web", "Brave New World");

// 使用substr改造
function replaceString(olds, news, fulls) {
  let oldsLen = olds.length;
  for (let i = 0; i < fulls.length; i++) {
    if (fulls.substr(i, oldsLen) == olds) {
      fulls = fulls.slice(0, i) + news + fulls.substr(i + oldsLen);
      console.log(fulls);
    }
  }
}
replaceString("World", "WebWorld", "Brave New World");

尝试把 Web 修改为 WebWorld 会出现死循环, 下面这种方式也许更好, 如果只是替换字符串, 使用 replace 更优

function replaceString(olds, news, fulls) {
  return fulls.split(olds).join(news);
}
replaceString("World", "WebWorld", "Brave New World");

附:基础