Skip to content

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提供了丰富的字符串操作方法,从基本的创建和访问,到高级的搜索、替换和国际化处理。掌握这些方法可以帮助你更有效地处理文本数据,编写更简洁、更高效的代码。

关键要点:

  1. 字符串在JavaScript中是不可变的,所有"修改"操作都会创建新字符串
  2. ES6引入的模板字符串提供了更强大的字符串功能
  3. 字符串查找方法包括indexOflastIndexOfincludesstartsWithendsWith
  4. 字符串提取方法包括slicesubstringsubstr
  5. 字符串可以通过split方法转换为数组,数组可以通过join方法转换为字符串
  6. 正则表达式是处理复杂字符串模式的强大工具
  7. 处理国际化字符串时,应考虑使用Intl对象和区域敏感的方法

通过合理使用这些方法,你可以有效地解决各种文本处理问题,提高代码的可读性和性能。

用知识点燃技术的火山