JavaScript字符串操作
字符串是JavaScript中最常用的数据类型之一,用于表示文本数据。JavaScript提供了丰富的字符串操作方法,使文本处理变得简单高效。本文将详细介绍JavaScript中的字符串创建、访问、操作和常用技巧。
字符串创建与基本属性
创建字符串
JavaScript中创建字符串有多种方式:
javascript
// 字符串字面量
const str1 = "双引号字符串";
const str2 = '单引号字符串';
const str3 = `模板字符串`; // ES6引入
// String构造函数
const str4 = new String("字符串对象"); // 创建String对象(不推荐)
注意:使用new String()
创建的是字符串对象,而不是基本字符串类型。通常应避免使用这种方式。
字符串长度
javascript
const greeting = "你好,世界!";
console.log(greeting.length); // 6(注意:中文字符在JavaScript中也是1个长度)
转义字符
javascript
// 常用转义字符
const text1 = "这是一行\n这是另一行"; // 换行符
const text2 = "姓名\t年龄"; // 制表符
const text3 = "他说:\"你好\""; // 引号
const text4 = "路径:C:\\Program Files"; // 反斜杠
模板字符串
ES6引入的模板字符串提供了更强大的字符串功能:
javascript
const name = "张三";
const age = 30;
// 字符串插值
const info = `${name}今年${age}岁`;
console.log(info); // "张三今年30岁"
// 多行字符串
const multiLine = `第一行
第二行
第三行`;
// 表达式计算
const price = 10;
const quantity = 5;
const total = `总价: ¥${price * quantity}`;
console.log(total); // "总价: ¥50"
字符串访问与比较
访问字符
javascript
const text = "JavaScript";
// 使用charAt()方法
console.log(text.charAt(0)); // "J"
console.log(text.charAt(4)); // "S"
// 使用方括号(类似数组,ES5+)
console.log(text[0]); // "J"
console.log(text[4]); // "S"
// 超出范围的访问
console.log(text.charAt(100)); // ""(空字符串)
console.log(text[100]); // undefined
字符串比较
javascript
// 使用比较运算符
console.log("apple" < "banana"); // true
console.log("apple" > "Apple"); // true(小写字母的Unicode码点大于大写字母)
// 使用localeCompare()方法(推荐用于国际化比较)
console.log("apple".localeCompare("banana")); // 负数,表示apple在banana前面
console.log("banana".localeCompare("apple")); // 正数,表示banana在apple后面
console.log("apple".localeCompare("apple")); // 0,表示相等
// 忽略大小写比较
console.log("Apple".toLowerCase() === "apple".toLowerCase()); // true
查找和提取
查找子字符串
javascript
const sentence = "JavaScript是一门强大的编程语言,JavaScript无处不在。";
// indexOf - 返回首次出现的索引,未找到返回-1
console.log(sentence.indexOf("JavaScript")); // 0
console.log(sentence.indexOf("JavaScript", 1)); // 17(从索引1开始查找)
console.log(sentence.indexOf("Python")); // -1(未找到)
// lastIndexOf - 从后向前查找,返回最后一次出现的索引
console.log(sentence.lastIndexOf("JavaScript")); // 17
console.log(sentence.lastIndexOf("JavaScript", 16)); // 0(从索引16开始向前查找)
// includes - 检查是否包含子字符串(ES6)
console.log(sentence.includes("强大")); // true
console.log(sentence.includes("Python")); // false
console.log(sentence.includes("JavaScript", 10)); // true(从索引10开始查找)
// startsWith - 检查是否以指定子字符串开头(ES6)
console.log(sentence.startsWith("JavaScript")); // true
console.log(sentence.startsWith("强大", 11)); // true(从索引11开始检查)
// endsWith - 检查是否以指定子字符串结尾(ES6)
console.log(sentence.endsWith("。")); // true
console.log(sentence.endsWith("语言", 16)); // true(检查前16个字符)
提取子字符串
javascript
const text = "JavaScript编程指南";
// slice - 提取子字符串,支持负索引
console.log(text.slice(0, 10)); // "JavaScript"
console.log(text.slice(10)); // "编程指南"
console.log(text.slice(-3)); // "程指南"
console.log(text.slice(-6, -3)); // "ava"
// substring - 类似slice,但不支持负索引,且会自动调整参数顺序
console.log(text.substring(0, 10)); // "JavaScript"
console.log(text.substring(10, 0)); // "JavaScript"(自动交换参数)
// substr - 第二个参数为长度(不推荐使用,已废弃)
console.log(text.substr(0, 10)); // "JavaScript"
console.log(text.substr(10, 3)); // "编程指"
console.log(text.substr(-3, 2)); // "程指"
修改字符串
字符串在JavaScript中是不可变的,所有"修改"操作实际上都是创建并返回一个新字符串。
大小写转换
javascript
const text = "Hello, World!";
// 转换为大写
console.log(text.toUpperCase()); // "HELLO, WORLD!"
// 转换为小写
console.log(text.toLowerCase()); // "hello, world!"
// 本地化大小写转换(考虑语言特性)
console.log(text.toLocaleLowerCase()); // "hello, world!"
console.log(text.toLocaleUpperCase()); // "HELLO, WORLD!"
// 原字符串不变
console.log(text); // "Hello, World!"
去除空白
javascript
const text = " Hello, World! ";
// 去除两端空白
console.log(text.trim()); // "Hello, World!"
// 去除开头空白(ES2019)
console.log(text.trimStart()); // "Hello, World! "
console.log(text.trimLeft()); // 同trimStart
// 去除结尾空白(ES2019)
console.log(text.trimEnd()); // " Hello, World!"
console.log(text.trimRight()); // 同trimEnd
填充字符串
javascript
// padStart - 在开头填充字符(ES2017)
console.log("5".padStart(3, "0")); // "005"
console.log("hello".padStart(10, "*")); // "*****hello"
// padEnd - 在结尾填充字符(ES2017)
console.log("5".padEnd(3, "0")); // "500"
console.log("hello".padEnd(10, "*")); // "hello*****"
替换内容
javascript
const text = "JavaScript是一门强大的语言,JavaScript很流行。";
// replace - 替换第一个匹配项
console.log(text.replace("JavaScript", "JS")); // "JS是一门强大的语言,JavaScript很流行。"
// 使用正则表达式替换所有匹配项
console.log(text.replace(/JavaScript/g, "JS")); // "JS是一门强大的语言,JS很流行。"
// replaceAll - 替换所有匹配项(ES2021)
console.log(text.replaceAll("JavaScript", "JS")); // "JS是一门强大的语言,JS很流行。"
// 使用函数进行替换
console.log(text.replace(/JavaScript/g, match => match.toUpperCase()));
// "JAVASCRIPT是一门强大的语言,JAVASCRIPT很流行。"
分割与连接
分割字符串
javascript
const text = "苹果,香蕉,橙子,葡萄";
// split - 分割字符串为数组
console.log(text.split(",")); // ["苹果", "香蕉", "橙子", "葡萄"]
console.log(text.split(",", 2)); // ["苹果", "香蕉"](限制结果数量)
console.log(text.split("")); // ["苹", "果", ",", "香", "蕉", ...](分割为单个字符)
console.log("hello".split("")); // ["h", "e", "l", "l", "o"]
// 使用正则表达式分割
const sentence = "Hello World! How are you?";
console.log(sentence.split(/\s+/)); // ["Hello", "World!", "How", "are", "you?"]
连接字符串
javascript
// 使用+运算符
const firstName = "张";
const lastName = "三";
console.log(firstName + lastName); // "张三"
// 使用concat方法(可连接多个字符串)
console.log("Hello".concat(" ", "World", "!")); // "Hello World!"
// 使用join方法(数组转字符串)
const fruits = ["苹果", "香蕉", "橙子"];
console.log(fruits.join()); // "苹果,香蕉,橙子"(默认以逗号分隔)
console.log(fruits.join("")); // "苹果香蕉橙子"
console.log(fruits.join(" - ")); // "苹果 - 香蕉 - 橙子"
字符串与Unicode
字符编码
javascript
const text = "A";
// charCodeAt - 返回指定位置字符的UTF-16编码
console.log(text.charCodeAt(0)); // 65
// codePointAt - 支持完整Unicode(ES6)
console.log("😀".codePointAt(0)); // 128512
// fromCharCode - 从UTF-16编码创建字符
console.log(String.fromCharCode(65)); // "A"
// fromCodePoint - 支持完整Unicode(ES6)
console.log(String.fromCodePoint(128512)); // "😀"
Unicode转义序列
javascript
// Unicode转义序列
console.log("\u00A9"); // "©"(版权符号)
console.log("\u{1F600}"); // "😀"(ES6扩展的Unicode表示法)
正则表达式与字符串
基本匹配
javascript
const text = "JavaScript是2023年最流行的编程语言之一。";
const regex1 = /\d+/; // 匹配一个或多个数字
const regex2 = /[a-zA-Z]+/; // 匹配一个或多个字母
// test - 检查是否匹配
console.log(regex1.test(text)); // true
console.log(/Python/.test(text)); // false
// match - 返回匹配结果
console.log(text.match(regex1)); // ["2023"]
console.log(text.match(regex2)); // ["JavaScript"]
// 使用g标志匹配所有结果
console.log(text.match(/[a-zA-Z]+/g)); // ["JavaScript"]
捕获组
javascript
const date = "2023-04-15";
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
// 使用exec
const result = dateRegex.exec(date);
console.log(result[0]); // "2023-04-15"(完整匹配)
console.log(result[1]); // "2023"(第一个捕获组)
console.log(result[2]); // "04"(第二个捕获组)
console.log(result[3]); // "15"(第三个捕获组)
// 使用match
const matchResult = date.match(dateRegex);
console.log(matchResult[1], matchResult[2], matchResult[3]); // "2023" "04" "15"
// 使用matchAll(ES2020)
const text = "电话: 010-12345678, 手机: 13912345678";
const phoneRegex = /(\d{2,3})-?(\d{8})/g;
const matches = [...text.matchAll(phoneRegex)];
console.log(matches[0][0], matches[0][1], matches[0][2]); // "010-12345678" "010" "12345678"
console.log(matches[1][0], matches[1][1], matches[1][2]); // "13912345678" "139" "12345678"
替换与正则表达式
javascript
const text = "电话: 010-12345678, 手机: 13912345678";
// 使用捕获组引用
const formatted = text.replace(/(\d{3})(\d{8})/g, "$1-$2");
console.log(formatted); // "电话: 010-12345678, 手机: 139-12345678"
// 使用函数进行复杂替换
const masked = text.replace(/\d(?=\d{4})/g, "*");
console.log(masked); // "电话: ***-****5678, 手机: *****5678"
高级字符串技巧
反转字符串
javascript
function reverseString(str) {
return str.split("").reverse().join("");
}
console.log(reverseString("Hello")); // "olleH"
// 注意:这种方法对于包含代理对(如表情符号)的字符串可能不正确
console.log(reverseString("😀😂")); // 可能显示不正确
// 处理Unicode的反转
function reverseUnicode(str) {
return [...str].reverse().join("");
}
console.log(reverseUnicode("😀😂")); // "😂😀"
计算字符串实际长度(考虑Unicode)
javascript
function getUnicodeLength(str) {
return [...str].length;
}
console.log("😀😂".length); // 4(每个表情占用2个代码单元)
console.log(getUnicodeLength("😀😂")); // 2(实际2个字符)
检查回文字符串
javascript
function isPalindrome(str) {
// 移除非字母数字字符并转为小写
const cleanStr = str.toLowerCase().replace(/[^a-z0-9]/g, "");
return cleanStr === cleanStr.split("").reverse().join("");
}
console.log(isPalindrome("A man, a plan, a canal: Panama")); // true
console.log(isPalindrome("race a car")); // false
截断字符串并添加省略号
javascript
function truncate(str, maxLength) {
if (str.length <= maxLength) return str;
return str.slice(0, maxLength - 3) + "...";
}
console.log(truncate("这是一段很长的文本内容,需要被截断", 10)); // "这是一段很长..."
驼峰命名转换
javascript
// 短横线/下划线命名转驼峰命名
function toCamelCase(str) {
return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase());
}
console.log(toCamelCase("background-color")); // "backgroundColor"
console.log(toCamelCase("user_name")); // "userName"
// 驼峰命名转短横线命名
function toKebabCase(str) {
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
}
console.log(toKebabCase("backgroundColor")); // "background-color"
格式化数字为千分位
javascript
function formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(formatNumber(1234567)); // "1,234,567"
字符串国际化
Intl.Collator - 字符串比较
javascript
// 创建针对中文的排序比较器
const collator = new Intl.Collator("zh-CN");
const fruits = ["苹果", "香蕉", "葡萄", "橙子"];
console.log(fruits.sort(collator.compare));
// 按中文拼音排序: ["苹果", "葡萄", "橙子", "香蕉"]
区域敏感的大小写转换
javascript
// 土耳其语中,i的大写不是I
console.log("i".toLocaleUpperCase("tr-TR")); // "İ"
console.log("i".toUpperCase()); // "I"(默认)
性能考虑
字符串连接优化
javascript
// 不好的做法(在循环中频繁连接字符串)
let result = "";
for (let i = 0; i < 1000; i++) {
result += i; // 每次都创建新字符串
}
// 更好的做法
const parts = [];
for (let i = 0; i < 1000; i++) {
parts.push(i);
}
const betterResult = parts.join("");
正则表达式优化
javascript
// 不好的做法(在循环中重复创建正则表达式)
function repeatReplace(text, count) {
for (let i = 0; i < count; i++) {
text = text.replace(/pattern/, "replacement");
}
return text;
}
// 更好的做法(预编译正则表达式)
const regex = /pattern/g;
function betterReplace(text, count) {
for (let i = 0; i < count; i++) {
text = text.replace(regex, "replacement");
}
return text;
}
总结
JavaScript提供了丰富的字符串操作方法,从基本的创建和访问,到高级的搜索、替换和国际化处理。掌握这些方法可以帮助你更有效地处理文本数据,编写更简洁、更高效的代码。
关键要点:
- 字符串在JavaScript中是不可变的,所有"修改"操作都会创建新字符串
- ES6引入的模板字符串提供了更强大的字符串功能
- 字符串查找方法包括
indexOf
、lastIndexOf
、includes
、startsWith
和endsWith
- 字符串提取方法包括
slice
、substring
和substr
- 字符串可以通过
split
方法转换为数组,数组可以通过join
方法转换为字符串 - 正则表达式是处理复杂字符串模式的强大工具
- 处理国际化字符串时,应考虑使用
Intl
对象和区域敏感的方法
通过合理使用这些方法,你可以有效地解决各种文本处理问题,提高代码的可读性和性能。