JavaScript学习笔记(三)之 Srting操作方法

String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串 。

1. 关于 Unicode

由于计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。在计算机中,1个字节(byte)由 8个比特(bit)组成,所以 1 个字节能表示的最大整数就是 255(28 个),如果想表示更大整数,就必须用更多的字节,比如 2 个字节可以表示的最大整数为 65535 ,即 216 个。

最早只有 127 个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为 ASCII 编码,比如大写字母 A 的编码是 65,小写字母 z 的编码是122。但如果要处理中文字符,显然一个字节是不够的,至少需要两个字节,所以,中国制定了GB2312 编码,用来把中文编进去。同样,其他国家的语言也会存在这个问题,因此,各国都制定了自己特有的编码规范。这样存在的问题是,在多语言混合的文本中,不同的编码会出现冲突,导致乱码出现。

如果想要解决这个问题,就需要制定一种通用的编码,能把所有语言都统一到一套编码里,统一进行管理,这种编码就是 Unicode 编码 。Unicode 通常用 2 个字节来表示独一无二的字符, 如果要用到非常偏僻的字符,就需要 4 个字节 。

因此,JavaScript 中的字符采用 16 位的 Unicode 编码来表示,也就是说,英文字符和中文字符都会占 2 个字节的空间大小。

2. 常用操作方法

作为字符串的基本包装对象,String 提供了以下几类方法来操作字符串:

[1] 字符操作:charAt 、charCodeAt、fromCharCode

charAt 用于获取指定位置上的字符,chatCodeAt 则是获取指定位置字符的 Unicode 编码(10进制表示),fromCharCode 是 String 上的一个静态方法,通过Unicode 获取对应的字符。

1
2
3
4
var str = 'abc';
str.charAt(1); // b
str.charCodeAt(1); // 98
String.fromCharCode(98); // a

[2] 字符串提取:substr、substring 、slice

这三个方法都可以对原字符串按位置进行提取,并返回一个新的字符串 。 其用法如下所示:

1
2
3
4
5
6
7
var stringValue = "hello world";
stringValue.slice(3); //"lo world"
stringValue.substring(3); //"lo world"
stringValue.substr(3); //"lo world"
stringValue.slice(3, 7); //"lo w"
stringValue.substring(3,7); //"lo w"
stringValue.substr(3, 7); //"lo worl"

如果传递的参数为负值,它们的表现会不尽相同:

1
2
3
4
5
6
7
var stringValue = "hello world";
stringValue.slice(-3); //"rld"
stringValue.substring(-3); //"hello world"
stringValue.substr(-3); //"rld"
stringValue.slice(3, -4); //"lo w"
stringValue.substring(3, -4); //"hel"
stringValue.substr(3, -4); //""(空字符串)

[3] 位置索引:indexOf 、lastIndexOf

indexOf() 方法从字符串的开头向后搜索子字符串,而 lastIndexOf() 方法是从字符串的末尾向前搜索子字符串。

1
2
3
var stringValue = "hello world";
stringValue.indexOf("o"); //4
stringValue.lastIndexOf("o"); //7

这两个方法都可以接收可选的第二个参数,表示从字符串中的哪个位置开始搜索。

1
2
3
var stringValue = "hello world";
stringValue.indexOf("o", 6); //7
stringValue.lastIndexOf("o", 6); //4

[4] 大小写转换:toLowerCase、toUpperCase

ECMAScript 中涉及字符串大小写转换的方法有4 个:toLowerCase()、toLocaleLowerCase()、toUpperCase() 和 toLocaleUpperCase()。其中,toLowerCase() 和 toUpperCase() 是两个经典的方法,借鉴自java.lang.String 中的同名方法。而 toLocaleLowerCase() 和toLocaleUpperCase() 方法则是针对特定地区的实现。对有些地区来说,针对地区的方法与其通用方法得到的结果相同,但少数语言(如土耳其语)会为 Unicode 大小写转换应用特殊的规则,这时候就必须使用针对地区的方法来保证实现正确的转换。

1
2
3
4
5
var stringValue = "hello world";
stringValue.toLocaleUpperCase(); //"HELLO WORLD"
stringValue.toUpperCase(); //"HELLO WORLD"
stringValue.toLocaleLowerCase(); //"hello world"
stringValue.toLowerCase(); //"hello world"

一般来说,在不知道自己的代码将在哪种语言环境中运行的情况下,还是使用针对地区的方法更稳妥一些。

[5] 模拟匹配:match、search、replace、split

match() 本质上与调用 RegExp 的 exec()方法相同。match() 方法只接受一个参数,要么是一个正则表达式,要么是一个 RegExp 对象。

1
2
3
4
5
6
7
var text = "cat, bat, sat, fat";
var pattern = /.at/;
//与pattern.exec(text)相同
var matches = text.match(pattern);
alert(matches.index); //0
alert(matches[0]); //"cat"
alert(pattern.lastIndex); //0

本例中的 match() 方法返回了一个数组;如果是调用RegExp 对象的 exec()方法并传递本例中的字符串作为参数,那么也会得到与此相同的数组:数组的第一项是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中的捕获组匹配的字符串。

search() 的唯一参数与 match() 方法的参数相同:由字符串或 RegExp 对象指定的一个正则表达式。search() 方法返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1。而且,search() 方法始终是从字符串开头向后查找模式。

1
2
3
var text = "cat, bat, sat, fat";
var pos = text.search(/at/);
aler t(pos); //1

replace() 接受两个参数:第一个参数可以是一个RegExp 对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(g)标志。

1
2
3
4
5
var text = "cat, bat, sat, fat";
var result = text.replace("at", "ond");
alert(result); //"cond, bat, sat, fat"
result = text.replace(/at/g, "ond");
aler t(result); //"cond, bond, sond, fond"

replace() 方法的第二个参数也可以是一个函数。在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3 个参数:模式的匹配项、模式匹配项在字符串中的位置和原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项……,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串。这个函数应该返回一个字符串,表示应该被替换的匹配项使用函数作为replace()方法的第二个参数可以实现更加精细的替换操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function htmlEscape(text) {
return text.replace(/[<>"&]/g, function (match, pos, originalText) {
switch (match) {
case "<":
return "<";
case ">":
return ">";
case "&":
return "&";
case "\"":
return """;
}
});
}

split() 可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。分隔符可以是字符串,也可以是一个RegExp 对象(这个方法不会将字符串看成正则表达式)。split()方法可以接受可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小。

1
2
3
4
var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(","); //["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2); //["red", "blue"]
var colors3 = colorText.split(/[^\,]+/); //["", ",", ",", ",", ""]