Appearance
13.4 字符串案例
案例 1:邮箱验证
需求:验证一个字符串是否是有效的邮箱地址
分析:
- 邮箱地址应该包含 @ 符号
- @ 符号前后都应该有内容
- @ 符号后面应该包含 . 符号
实现:
java
public class EmailValidationExample {
public static void main(String[] args) {
String[] emails = {
"user@example.com",
"invalid-email",
"user@",
"@example.com",
"user@example",
"user.name@example.com",
"user_name@example.com",
"user-name@example.com",
"user@sub.example.com"
};
for (String email : emails) {
System.out.println("邮箱: " + email);
System.out.println("是否有效: " + isValidEmail(email));
System.out.println();
}
}
public static boolean isValidEmail(String email) {
// 检查是否为 null 或空字符串
if (email == null || email.isEmpty()) {
return false;
}
// 检查是否包含 @ 符号
int atIndex = email.indexOf('@');
if (atIndex == -1) {
return false;
}
// 检查 @ 符号是否在开头或结尾
if (atIndex == 0 || atIndex == email.length() - 1) {
return false;
}
// 检查 @ 符号后是否包含 . 符号
String domain = email.substring(atIndex + 1);
if (!domain.contains(".")) {
return false;
}
// 检查 . 符号是否在域名的开头或结尾
int dotIndex = domain.indexOf('.');
if (dotIndex == 0 || dotIndex == domain.length() - 1) {
return false;
}
return true;
}
}案例 2:手机号验证
需求:验证一个字符串是否是有效的中国大陆手机号
分析:
- 手机号应该由 11 位数字组成
- 手机号应该以 1 开头
- 第二位应该是 3-9 之间的数字
实现:
java
public class PhoneValidationExample {
public static void main(String[] args) {
String[] phones = {
"13812345678",
"15987654321",
"18812345678",
"19987654321",
"12345678901", // 第二位不是 3-9
"1381234567", // 不足 11 位
"138123456789", // 超过 11 位
"1381234567a" // 包含非数字字符
};
for (String phone : phones) {
System.out.println("手机号: " + phone);
System.out.println("是否有效: " + isValidPhone(phone));
System.out.println();
}
}
public static boolean isValidPhone(String phone) {
// 检查是否为 null 或空字符串
if (phone == null || phone.isEmpty()) {
return false;
}
// 检查长度是否为 11
if (phone.length() != 11) {
return false;
}
// 检查是否全为数字
for (char c : phone.toCharArray()) {
if (!Character.isDigit(c)) {
return false;
}
}
// 检查第一位是否为 1
if (phone.charAt(0) != '1') {
return false;
}
// 检查第二位是否为 3-9
char secondChar = phone.charAt(1);
if (secondChar < '3' || secondChar > '9') {
return false;
}
return true;
}
}案例 3:密码强度检查
需求:检查密码的强度,根据密码的复杂度给出不同的强度等级
分析:
- 弱密码:长度小于 8,或只包含一种字符类型
- 中等密码:长度大于等于 8,包含至少两种字符类型
- 强密码:长度大于等于 10,包含至少三种字符类型
实现:
java
public class PasswordStrengthExample {
public static void main(String[] args) {
String[] passwords = {
"123456", // 弱密码
"password", // 弱密码
"Password123", // 中等密码
"Password123!", // 强密码
"P@ssw0rd123" // 强密码
};
for (String password : passwords) {
System.out.println("密码: " + password);
System.out.println("强度等级: " + getPasswordStrength(password));
System.out.println();
}
}
public static String getPasswordStrength(String password) {
// 检查是否为 null 或空字符串
if (password == null || password.isEmpty()) {
return "弱密码";
}
int length = password.length();
boolean hasUpper = false;
boolean hasLower = false;
boolean hasDigit = false;
boolean hasSpecial = false;
// 检查密码中的字符类型
for (char c : password.toCharArray()) {
if (Character.isUpperCase(c)) {
hasUpper = true;
} else if (Character.isLowerCase(c)) {
hasLower = true;
} else if (Character.isDigit(c)) {
hasDigit = true;
} else {
hasSpecial = true;
}
}
// 计算密码强度等级
int strength = 0;
if (hasUpper) strength++;
if (hasLower) strength++;
if (hasDigit) strength++;
if (hasSpecial) strength++;
if (length < 8 || strength < 2) {
return "弱密码";
} else if (length < 10 || strength < 3) {
return "中等密码";
} else {
return "强密码";
}
}
}案例 4:字符串反转
需求:将一个字符串反转
分析:
- 可以使用 StringBuilder 的 reverse() 方法
- 可以使用 char 数组手动反转
实现:
java
public class StringReverseExample {
public static void main(String[] args) {
String[] strings = {
"Hello, Java!",
"12345",
"abcdefg",
"racecar", // 回文
""
};
for (String str : strings) {
System.out.println("原始字符串: " + str);
System.out.println("反转后: " + reverseString(str));
System.out.println("是否是回文: " + isPalindrome(str));
System.out.println();
}
}
// 方法 1:使用 StringBuilder
public static String reverseString(String str) {
if (str == null) {
return null;
}
StringBuilder sb = new StringBuilder(str);
return sb.reverse().toString();
}
// 方法 2:使用 char 数组
public static String reverseString2(String str) {
if (str == null) {
return null;
}
char[] charArray = str.toCharArray();
int left = 0;
int right = charArray.length - 1;
while (left < right) {
char temp = charArray[left];
charArray[left] = charArray[right];
charArray[right] = temp;
left++;
right--;
}
return new String(charArray);
}
// 检查是否是回文
public static boolean isPalindrome(String str) {
if (str == null) {
return false;
}
return str.equals(reverseString(str));
}
}案例 5:字符串统计
需求:统计字符串中各种字符的数量
分析:
- 统计大写字母、小写字母、数字、空格和其他字符的数量
实现:
java
public class StringStatisticsExample {
public static void main(String[] args) {
String[] strings = {
"Hello, Java! 123",
"The quick brown fox jumps over the lazy dog",
"1234567890",
"!@#$%^&*()",
""
};
for (String str : strings) {
System.out.println("字符串: " + str);
printStatistics(str);
System.out.println();
}
}
public static void printStatistics(String str) {
if (str == null) {
System.out.println("字符串为 null");
return;
}
int upperCase = 0;
int lowerCase = 0;
int digits = 0;
int spaces = 0;
int others = 0;
for (char c : str.toCharArray()) {
if (Character.isUpperCase(c)) {
upperCase++;
} else if (Character.isLowerCase(c)) {
lowerCase++;
} else if (Character.isDigit(c)) {
digits++;
} else if (Character.isWhitespace(c)) {
spaces++;
} else {
others++;
}
}
System.out.println("大写字母: " + upperCase);
System.out.println("小写字母: " + lowerCase);
System.out.println("数字: " + digits);
System.out.println("空格: " + spaces);
System.out.println("其他字符: " + others);
System.out.println("总长度: " + str.length());
}
}案例 6:单词计数
需求:统计字符串中单词的数量
分析:
- 单词是由空格分隔的连续字符
- 需要处理多个连续空格的情况
实现:
java
public class WordCountExample {
public static void main(String[] args) {
String[] strings = {
"Hello, Java!",
"The quick brown fox jumps over the lazy dog",
" Multiple spaces here ",
"SingleWord",
""
};
for (String str : strings) {
System.out.println("字符串: '" + str + "'");
System.out.println("单词数量: " + countWords(str));
System.out.println("单词列表:");
for (String word : getWords(str)) {
System.out.println("- " + word);
}
System.out.println();
}
}
public static int countWords(String str) {
if (str == null || str.trim().isEmpty()) {
return 0;
}
// 使用正则表达式分割单词,\s+ 表示一个或多个空格
String[] words = str.trim().split("\\s+");
return words.length;
}
public static String[] getWords(String str) {
if (str == null || str.trim().isEmpty()) {
return new String[0];
}
return str.trim().split("\\s+");
}
}案例 7:首字母大写
需求:将字符串中每个单词的首字母大写
分析:
- 分割字符串为单词
- 将每个单词的首字母大写
- 重新组合单词
实现:
java
public class CapitalizeFirstLetterExample {
public static void main(String[] args) {
String[] strings = {
"hello, java!",
"the quick brown fox",
"java programming",
" multiple spaces ",
""
};
for (String str : strings) {
System.out.println("原始字符串: '" + str + "'");
System.out.println("首字母大写: '" + capitalizeFirstLetter(str) + "'");
System.out.println();
}
}
public static String capitalizeFirstLetter(String str) {
if (str == null || str.trim().isEmpty()) {
return str;
}
// 分割字符串为单词
String[] words = str.trim().split("\\s+");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < words.length; i++) {
String word = words[i];
if (word.length() > 0) {
// 首字母大写,其余小写
String capitalizedWord = word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
sb.append(capitalizedWord);
if (i < words.length - 1) {
sb.append(" ");
}
}
}
return sb.toString();
}
}案例 8:字符串压缩
需求:对字符串进行简单的压缩,如将 "aaabbbccc" 压缩为 "a3b3c3"
分析:
- 遍历字符串,统计连续相同字符的数量
- 当遇到不同字符时,记录前一个字符及其数量
实现:
java
public class StringCompressionExample {
public static void main(String[] args) {
String[] strings = {
"aaabbbccc",
"aabbaa",
"abc",
"a",
""
};
for (String str : strings) {
System.out.println("原始字符串: " + str);
System.out.println("压缩后: " + compressString(str));
System.out.println();
}
}
public static String compressString(String str) {
if (str == null || str.length() <= 1) {
return str;
}
StringBuilder sb = new StringBuilder();
char currentChar = str.charAt(0);
int count = 1;
for (int i = 1; i < str.length(); i++) {
if (str.charAt(i) == currentChar) {
count++;
} else {
sb.append(currentChar).append(count);
currentChar = str.charAt(i);
count = 1;
}
}
// 处理最后一组字符
sb.append(currentChar).append(count);
// 如果压缩后的字符串长度大于等于原字符串,返回原字符串
return sb.length() < str.length() ? sb.toString() : str;
}
}案例 9:字符串替换
需求:将字符串中的特定字符或字符串替换为其他内容
分析:
- 使用 String 的 replace() 方法
- 使用 replaceAll() 方法处理正则表达式
实现:
java
public class StringReplacementExample {
public static void main(String[] args) {
String text = "Hello, Java! Java is a programming language. Java is widely used.";
System.out.println("原始文本: " + text);
System.out.println();
// 替换单个字符
String replaced1 = text.replace('J', 'j');
System.out.println("替换 'J' 为 'j': " + replaced1);
System.out.println();
// 替换字符串
String replaced2 = text.replace("Java", "Python");
System.out.println("替换 'Java' 为 'Python': " + replaced2);
System.out.println();
// 使用正则表达式替换
String replaced3 = text.replaceAll("Java", "C++");
System.out.println("使用正则表达式替换 'Java' 为 'C++': " + replaced3);
System.out.println();
// 替换多个空格为单个空格
String textWithSpaces = "Hello, Java! How are you?";
System.out.println("原始文本(含多个空格): '" + textWithSpaces + "'");
String replaced4 = textWithSpaces.replaceAll("\\s+", " ");
System.out.println("替换多个空格为单个空格: '" + replaced4 + "'");
}
}案例 10:文件路径处理
需求:处理文件路径,提取文件名和扩展名
分析:
- 使用 lastIndexOf() 方法找到最后一个 / 或 \ 来提取文件名
- 使用 lastIndexOf() 方法找到最后一个 . 来提取扩展名
实现:
java
public class FilePathExample {
public static void main(String[] args) {
String[] paths = {
"C:\\Users\\John\\Documents\\example.txt",
"/home/user/projects/java/Hello.java",
"example.jpg",
"C:\\Program Files\\Java\\jdk1.8.0_251\\bin\\javac.exe",
""
};
for (String path : paths) {
System.out.println("文件路径: " + path);
System.out.println("文件名: " + getFileName(path));
System.out.println("扩展名: " + getFileExtension(path));
System.out.println();
}
}
public static String getFileName(String path) {
if (path == null || path.isEmpty()) {
return "";
}
// 找到最后一个 / 或 \
int lastSeparatorIndex = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
if (lastSeparatorIndex == -1) {
return path;
}
return path.substring(lastSeparatorIndex + 1);
}
public static String getFileExtension(String path) {
if (path == null || path.isEmpty()) {
return "";
}
String fileName = getFileName(path);
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex == -1 || lastDotIndex == fileName.length() - 1) {
return "";
}
return fileName.substring(lastDotIndex + 1);
}
}总结
通过这些案例,我们学习了如何使用字符串的各种方法来解决实际问题,包括:
- 验证类案例:邮箱验证、手机号验证、密码强度检查
- 操作类案例:字符串反转、首字母大写、字符串压缩
- 统计类案例:字符串统计、单词计数
- 替换类案例:字符串替换
- 解析类案例:文件路径处理
这些案例展示了字符串在实际开发中的广泛应用,通过合理使用字符串的方法,可以有效地解决各种字符串处理问题。
