es-string

字符串

通过临时转换成包装类来调用

Unicode 编码

UTF-8 万国码

字符串中使用转移字符\u 输出,16 进制位

console.log(“\u0031”) //1

在 HTML 页面中:&#编码;

10 进制位

charCodeAt()

fromCharCode()

字符的 Unicode 表示法

codePointAt()

String.fromCharCode()

String 构造函数

String 全局对象是一个用于字符串或一个字符序列的构造函数。

你也能使用 String 函数将其他值生成或转换成字符串:

String(thing)
new String(thing)

参数

转义字符 Escape Sequence

除了普通的可打印字符以外,一些特殊有特殊功能的字符可以通过转义字符的形式放入字符串中:

escape sequence Output
\0 空字符
\' 单引号
\" 双引号
\\ 反斜杠
\n 换行
\r 回车
\v 垂直制表符
\t 水平制表符
\b 退格
\f 换页
\uXXXX unicode 码
\u{X} ... \u{XXXXXX} unicode codepoint
\xXX Latin-1 字符 (x 小写)

长字符串

有时,你的代码可能含有很长的字符串。你可能想将这样的字符串写成多行,而不是让这一行无限延长或着被编辑器折叠。有两种方法可以做到这一点。

其一,可以使用 + 运算符将多个字符串连接起来,如下所示:

let longString = "This is a very long string which needs " +
                 "to wrap across multiple lines because " +
                 "otherwise my code is unreadable.";

其二,可以在每行末尾使用反斜杠字符(“\”),以指示字符串将在下一行继续。确保反斜杠后面没有空格或任何除换行符之外的字符或缩进; 否则反斜杠将不会工作

let longString = "This is a very long string which needs \
to wrap across multiple lines because \
otherwise my code is unreadable.";

字符串的比较

熟练使用 C 语言的开发者经常使用 strcmp 函数来比较字符串,但在 JavaScript 中,你只需要使用 比较操作符(>/=/<=)

var a = "a";
var b = "b";
if (a < b) // true
  print(a + " is less than " + b);
else if (a > b)
  print(a + " is greater than " + b);
else
  print(a + " and " + b + " are equal.");

使用从字符串实例继承而来的 localeCompare 方法也能达到同样的效果。

字符串属性

Length 属性

获取字符串的长度

索引

索引属性只读,不可用于赋值 @@@

如果传入负值?无效

字符串的方法

字符串的所有方法都不会对原字符串造成影响,因为这些都是包装类的方法,而 string 是基础数据类型 @@@

charAt()

根据索引获取指定的字符

不如 [] 来得方便

var str = "hello"
console.log(str[0]) //h

charCodeAt()

参数

返回值

"ABC".charCodeAt(0) // returns 65:"A"
"ABC".charCodeAt(1) // returns 66:"B"
"ABC".charCodeAt(2) // returns 67:"C"
"ABC".charCodeAt(3) // returns NaN

codePointAt() @@@

'ABC'.codePointAt(1);          // 66
'\uD800\uDC00'.codePointAt(0); // 65536

String.fromChartCode()

String.fromCodePoint() @@@

构造函数的静态方法

ES5 提供 String.fromCharCode() 方法,用于从 Unicode 码点返回对应字符,但是这个方法不能识别码点大于 0xFFFF 的字符。

String.fromCharCode(0x20BB7)
// "ஷ"

上面代码中,String.fromCharCode() 不能识别大于 0xFFFF 的码点,所以 0x20BB7 就发生了溢出,最高位 2 被舍弃了,最后返回码点 U+0BB7 对应的字符,而不是码点 U+20BB7 对应的字符。

ES6 提供了 String.fromCodePoint() 方法,可以识别大于 0xFFFF 的字符,弥补了 String.fromCharCode() 方法的不足。在作用上,正好与下面的 codePointAt() 方法相反。

String.fromCodePoint(0x20BB7)
// "𠮷"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true

上面代码中,如果 String.fromCodePoint 方法有多个参数,则它们会被合并成一个字符串返回。

注意,fromCodePoint 方法定义在 String 对象上,而 codePointAt 方法定义在字符串的实例对象上。

toLowerCase()

将字符串转换为小写并返回

toUpperCase()

将字符串转换为大写并返回

slice() @@@

可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量

数组中也有类似的同名方法

参数

splice 是数组的方法,字符串要想实现删除指定索引要怎么做呢?

可以转换成数组操作,或者重新拼接

exception

描述

substr()

substring()

concat()

concat 方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。 concat 方法并不影响原字符串。

拼串操作 使用 赋值操作符(+, +=)代替此方法,因为性能

trim()

去除字符串两端的空格

repeat()

ES6

repeat 方法返回一个新字符串,表示将原字符串重复 n 次。

参数

返回值

Exceptions

示例

  'x'.repeat(3) // "xxx"
  'hello'.repeat(2) // "hellohello"
  'na'.repeat(0) // ""

padStart(),padEnd()

ES8 新增

padStart() 方法用另一个字符串填充当前字符串 (重复,如果需要的话),以便产生的字符串达到给定的长度。填充从当前字符串的开始**(左侧)**应用的。

padEnd() 方法会用一个字符串填充当前字符串(如果需要的话则重复填充),从当前字符串的末尾**(右侧)**开始填充。

参数

返回值

字符串的搜索

indexOf()

lastIndexOf()

从一个字符串中检索指定内容

参数

返回值

描述

注意

includes()

ES6

includes() 方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。

参数

position 和 fromIndex 是两种形参名,因为他们的表现不一致

返回值

注意

startsWith(), endsWith()

ES6

endsWith() 方法用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回 truefalse

参数

返回值

注意

FAQ

#faq/js

多行字符串拼接

模板字符串, 中间的空格无法消除

es-string

数组 join

在字符串索引处插入

转化为数组,使用 splice(index,0,str)

使用 slice(),截断再拼接

删除 String 里某个字符的方法

使用 replace

var str = "abcdaabbssaaa";
var reg = new RegExp("a","g");
var a = str.replace(reg,"");
console.log(a);

使用 split

var str = "abcdaabbssaaa";
var a = str.split("a").join("");
console.log(a);

删除指定索引的字符

转换为数组

var result = S.split('');
result.splice(bindex, eindex - bindex);
S = result.join('');

重新拼接

删除最后一个字符

  var string = "2017-06-26";
  var reg = /\w$/
  
  console.log(string.replace(reg,""))

或者使用 slice 方法

交换字符串的两个单词

下面的例子演示了如何交换一个字符串中两个单词的位置,这个脚本使用 $1 和 $2 代替替换文本。

  var re = /(\w+)\s(\w+)/;
  var str = "John Smith";
  var newstr = str.replace(re, "$2, $1");
  // Smith, John
  console.log(newstr);

大写字母位移

把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。

按照 Unicode 编码,找出所有大写字母,然后移到最后即可。

注意:不能申请额外的空间,常数级的空间就 OK

function moveChar (str){
  // [A-Z] 65-90

  let len =  str.length
  let upper = ''
  for (let i = 0; i < len;) {
    if(str.charCodeAt(i)>=65 && str.charCodeAt(i)<=90){
      // 是大写字母,移动到最后
      upper += str[i]
      // 如何删除一个字符?
      let tempA = str.slice(0,i)
      let tempB = str.slice(i+1)
      str = tempA + tempB
    }else{
      i++
    }
  }
  return str+upper
}

console.log(moveChar('AkleBiCeilD'))
  function moveChar (str){
    // [A-Z] 65-90
    let upper = ''
    let lower = str.replace(/([A-Z])/g,function(match,p,offset,string){
      // 操作str,在最后拼上即可
      // string += p
      // 解决死循环的问题,不能直接加在原本的str,新建一个保存即可
      upper += p
      // 返回值作为匹配的字符的替换值,相当于是删除了匹配字符
      return ""
    })
  
    // replace 全局替换完毕
    return lower + upper
  }
  
  console.log(moveChar('AkleBiCeilD'))

生成一段填充字符串

先调用数组的 fill 方法,再转换成字符串

使用 Array.from()

Array.from({ length: 2 }, () => 'jack')
// ['jack', 'jack']

使用 ES8 的 padStart/End 方法

推荐方案: 使用 repeat 方法

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

字典排序

根据字母的 unicode 编码调整字符串的字母位置

https://leetcode.cn/problems/orderly-queue/submissions/

字符串是可以直接比较大小和 sort 的,默认就是按照 unicode 编码来比较

k>2 其实就是冒泡排序

字符串首字母大写:capitalize

情况有:

  1. 一个句子中所有的单词的首字母大写
  2. 一个句子中只有第一个单词的首字母需要大写
  3. 只有一个单词,然后这个单词首字母大写即可,情况三同时是 1 和 2 的子集
  4. 相似但完全不同的 case:页面中的样式,实现上述的效果,直接使用 text-transform: capitalize; 即可

exception:

  1. 参数有可能是 undefine 或者 null
  2. 参数是否有 charAt replace 等方法,还是直接判断是否是字符串最直接,如果不是字符串返回原值

通过函数重载处理

function capitalize(val: string): string;
function capitalize<T>(val: T): T;
function capitalize<T>(val: string | T): string | T {
    if(typeof val === 'string') {
        _capitalize(val);
    }
    else {
        return val;
    }
}

情况二

方法也不少试一下哪个效率好一点

方法一

function _capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

function _capitalize(str) {
    return str[0].toUpperCase() + str.slice(1);
}

方法二:非空首字母

function firstUpperCase(val) {
    return val.replace(/^\S/, function (s) {
        return s.toUpperCase();
    });
}
// 10,889,187 operations/sec
function capitalizeFirstLetter(string) {
    return string[0].toUpperCase() + string.slice(1);
}

// 10,875,535 operations/sec
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 4,632,536 operations/sec
function capitalizeFirstLetter(string) {
    return string.replace(/^./, string[0].toUpperCase());
}

// 1,977,828 operations/sec
String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

字符串大小写判断

520. 检测大写字母

字符串压缩

存粹算法上的压缩,原理不太清楚,但是压缩效率是有限的,把字符串压缩成二进制 buffer 存储

服务器的短链接,本质是键值对,用一个短链接对应一个存储在数据库的长连接,并没有真正的节省空间

535. TinyURL 的加密与解密 - 力扣(LeetCode)