字符串是 JavaScript 的一种基本数据类型。String 类提供了操作原始字符串值的方法。String 对象的 length 属性声明了该字符串中的字符数。类 String 定义了大量操作字符串的方法,例如从字符串中提取字符或子串,或者检索字符或子串。
注意:JavaScript 的字符串是不可变 (immutable) 的,String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。
在 JavaScript 1.2 及其后版本的 Netscape 实现中,字符串的行为就像只读的字符数组。例如,从字符串 s 中提取第三个字符,可以用 s[2] 代替更加标准的 s.charAt(2)。此外,对字符串应用 for/in 循环时,它将枚举字符串中每个字符的数组下标(但要注意,ECMAScript 标准规定,不能枚举 length 属性)。因为 Netscape 实现中的字符串的数组行为不标准,所以应该避免使用它。
new String(s) // 构造函数 String(s) // 构造函数
参数
s:要存储在String对象中或转换成原始字符串的值。
返回值
当 String() 与 new 运算符一起作为构造函数使用时,返回一个新创建的 String 对象,存放的是字符串 s 或 s 的字符串表示。当不用 new 运算符调用 String() 时,它只把 s 转换成原始的字符串,并返回转换后的值。
字符串 String 类提供的多个方法均能使用正则表达式,如下:
语法
string.match(regexp)
参数
regexp:声明了要匹配的模式的RegExp对象。如果该参数不是RegExp对象,则首先将把它传递给RegExp()构造函数,把它转换成RegExp对象。
描述
方法 match() 将检索字符串 string,以找到一个或多个与 regexp 匹配的文本。这个方法的行为很大程度上依赖于 regexp 是否具有性质 g(全局搜索)。
如果 regexp 没有性质 g,那么 match() 就只能在 string 中执行一次匹配,如果没有找到任何匹配的文本,match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性:
index 属性声明的是匹配文本的起始字符在 string 中的位置
input 属性声明的是对 string 的引用
实例:下面的非全局匹配使用了更加复杂的正则表达式,它具有几个用括号括起来的子表达式。与该表达式匹配的是一个 URL,与它的子表达式匹配的是那个 URL的协议部分、主机部分和路径部分:
var url = /(\w+):\/\/([\w.]+)\/(\S*)/; var text = "Visit my home page at http://www.isp.com/~david"; var result = text.match(url); if (result != null) { var fullurl = result[0]; var protocol = result[1]; var host = result[2]; var path = result[3]; console.log(fullurl); // 包含 "http://www.isp.com/~david" console.log(protocol); // 包含 "http" console.log(host); // 包含 "www.isp.com" console.log(path); // 包含 "~david" }
如果 regexp 具有标志 g,那么 match() 将执行全局检索,找到 string 中的所有匹配子串。如果没有找到任何匹配的子串。它将返回 null。如果找到了一个或多个匹配子串,它将返回一个数组。不过,全局匹配返回的数组的内容与前者大不相同,它的数组元素存放的是 string 中的所有匹配子串,而且它也没有 index 属性和 input 属性。
注意:在全局匹配的模式下,match()既不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果你需要这些全局检索的信息,可以使用RegExp.exec()。
实例:下面的全局匹配可以找到字符串中的所有数字:
var result = "1 plus 2 equals 3".match(/\d+/g); console.log(result); // 输出 ["1", "2", "3"]
语法
string.replace(regexp, replacement)
参数
regexp:声明了要替换的模式的RegExp对象。如果该参数是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换成RegExp对象。
replacement:一个字符串,声明的是替换文本或生成替换文本的函数。详见描述部分。
返回值
一个新字符串,是用replacemenc替换了与regexp的第一次匹配或所有匹配之后得到的。
描述
字符串 string 的方法 replace() 执行的是查找并替换的操作。它将在 string 中查找与 regexp 相匹配的子串,然后用 replacement 替换这些子串。如果 regexp 具有全局性质 g,那么 replace() 将替换所有的匹配子串。否则,它只替换第一个匹配子串。
注意:replacement 可能是字符串或函数。如果它是一个字符串,那么每个匹配都将由字符串替换。但 replacement 中的 $ 字符具有特殊的含义。如下表所示,它说明从模式匹配得到的字符串将用于替换:
$1, $2, ... $99:与 regexp 中的第 1 到第 99 个子表达式相匹配的文本
$&:与 regexp 相匹配的子串
$`:位于匹配子串左侧的文本
$':位于匹配子串右侧的文本
$$:直接量$符号
ECMAScript v3 规定,replace() 方法的参数 replacement 可以是函数而不是字符串,JavaScipt 1.2 和 JScript 5.5 实现了这一特性。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。接下来参数是一个整数,声明了匹配在 string 中出现的位置。最后一个参数是 string 自身。
实例
(1)将文本中的 “javascript” 字符串替换成 “JavaScript” 文本,代码如下:
var text = "hello javascript!"; text = text.replace(/javascript/i, "JavaScript"); console.log(text); // 输出:hello JavaScript!
(2)将名字 “Doe,John” 转换成 “JohnDoe” 的形式,代码如下:
var name = "Doe,John"; name = name.replace(/(\w+)\s*,\s*(\w+)/, "$2 $1"); console.log(name); // 输出:Doe,John
(3)用花引号替换直引号,代码如下:
var text = "\"javascript\""; text = text.replace(/"([^"]*)"/g, "``$1''"); console.log(text); // 输出:``javascript''
(4)使字符串中所有单词的第一个字母都是大写的,代码如下:
var text = "hello javascript!"; text = text.replace(/\b\w+\b/g, function(word) { return word.substring(0,1).toUpperCase() + word.substring(1); }); console.log(text); // 输出:Hello Javascript!
语法
string.search(regexp)
参数
regexp 要在字符串 string 中检索的 RegExp 对象,该对象具有指定的模式。如果该参数不是 RegExp 对象,则首先将它传递给 RegExp() 构造函数,把它转换成 RegExp 对象。
返回值
string 中第一个与 regexp 相匹配的子串的起始位置。如果没有找到任何匹配的子串,则返回-1。
描述
方法 search() 将在字符串 string 中检索与 regexp 相匹配的子串,并且返回第一个匹配子串的第一个字符的位置。如果没有找到任何匹配的子串,则返回-1。
search() 并不执行全局匹配,它将忽略标志g。它也忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始处进行检索,这意味着它总是返回 string 的第一个匹配的位置。
示例
var str = "JavaScript is fun"; var a = str.search(/script/i) // 返回 4 console.log(a); var b = str.search(/a(.)a/) // 返回 1 console.log(b)
语法
string.split(delimiter, limit)
参数
delimiter:字符串或正则表达式,从该参数指定的地方分割string。ECMAScript V3标准化了正则表达式作为定界符使用时的用法,JavaScript 1.2 和 JScript 3.0 实现了它。JavaScriptl.1 没有实现它。
limit:这个可选的整数指定了返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数字。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。ECMAScriptv3 标准化了该参数,JavaScript 1.2 和 JScript 3.0 实现了它。JavaScript 1.1 没有实现它。
返回值
一个字符串数组,是通过在delimiter指定的边界处将字符串string分割成子串创建的。返回的数组中的子串不包括delimiter自身,但下面列出的情况除外。
描述
方法 split() 将创建并返回一个字符串数组,该数组中的元素是指定的字符串 string 的子串,最多具有limit个。这些子串是通过从头到尾检索字符串中与 delimiter 匹配的文本,在匹配文本之前和之后分割 string 得到的。返回的子串中不包括定界符 文本(下面提到的情况除外)。如果定界符从字符串开头开始匹配,返回的数组的第一个元素是空串,即出现在定界符之前的文本。同样,如果定界符与字符串的结尾匹 配,返回的数组的最后一个元素也是空串(假定与 limit 没有冲突)。
如果没有指定 delimiter,那么它根本就不对 string 执行分割,返回的数组中只有一个元素,而不分割字符串元素。如果 delimiter 是一个空串或与空串匹配的正则表 达式,那么 string 中的每个字符之间都会被分割,返回的数组的长度与字符串长度相等 (假定王imic不小于该长度)。(注意,这是一种特殊情况,因为没有匹配第一个字符之前和最后一个字符之后的空串。)
前面说过,该方法返回的数组中的子串不包括用于分割字符串的定界符文本。但如果 delimiter 是包括子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹 配的子串(但不包括与整个正则表达式匹配的文本)。
注意:String.split() 执行的操作与 Array.join() 执行的操作相反。
示例
在使用结构复杂的字符串时,方法split()最有用。例如:
"1:2:3:4:5".split(":"); // 返回 ["1","2","3","4","5"] "|a|b|c|".split("|"); // 返回 ["", "a", "b", "c", ""]
split()方法的另—个常见用法是解析命令和与之相似的字符串,用空格将它们分割 成单词:
var words = sentence.split(' ');
关于delimiter是一个空格的情况,详见“Bug'’小节。用正则表达式作为定界符, 很容易把字符串分割成单词:
var words = sentence.split(/\s+/);
要把字符串分割成字符数组,可以用空串作为定界符。如果只想把字符串的前一部分 分割成字符数组,需要使用limit参数:
"hello".split(""); // 返回 ["h","e","l","l","o"] "hello".split("", 3); // 返回 ["h","e","l"]
如果想使返回的数组包括定界符或定界符的一个或多个部分,可以使用带子表达式的正则表达式。例如,下面的代码将在HTML标记处分割字符串,返回的数组中包括这些标记:
var text = "hello <b>world</b>"; text.split(/(<[^>]*>)/); // 返回 ["hello ","<b>","world","</b>",""]