Java中含特殊字符的字符串首字母及单词首字母大写实现方法
Hey there! Let's break down your two Java string capitalization questions step by step—these are super common pain points when working with text that has special characters like * or -.
If you've got a string like *-hello and want to turn it into *-Hello (keep the leading special chars, capitalize the first actual letter), you've got two solid approaches:
Approach 1: Manual Character Traversal
Simple and straightforward—no regex needed, just iterate until you find the first letter:
public static String capitalizeFirstLetterAfterSpecialChars(String input) { if (input == null || input.isEmpty()) { return input; } char[] charArray = input.toCharArray(); boolean foundFirstLetter = false; for (int i = 0; i < charArray.length; i++) { if (Character.isLetter(charArray[i]) && !foundFirstLetter) { charArray[i] = Character.toUpperCase(charArray[i]); foundFirstLetter = true; break; // Stop after capitalizing the first valid letter } } return new String(charArray); }
How it works: It skips all leading non-letter characters (like *, -, etc.) until it hits the first alphabetic character, then capitalizes it and stops. Perfect for cases where you only care about the first meaningful letter.
Approach 2: Regex Replacement
If you prefer a more concise solution, use replaceFirst to target the first letter after leading special chars:
public static String capitalizeFirstLetterWithRegex(String input) { if (input == null || input.isEmpty()) { return input; } // Match leading non-letters + first lowercase letter, capitalize the letter return input.replaceFirst("([^a-zA-Z]*)([a-z])", "$1" + "$2".toUpperCase()); }
Regex breakdown:
[^a-zA-Z]*: Matches any number of leading non-alphabetic characters([a-z]): Captures the first lowercase letter$1: Keeps the leading special chars intact,$2.toUpperCase()capitalizes the captured letter
The default WordUtils.capitalizeFully only splits words by spaces, which won't handle * or - as word separators. Here's how to fix that:
Option 1: Use WordUtils' Delimiter Overload
The capitalizeFully method has an overload that lets you define custom word delimiters. Just pass in *, -, and spaces as your delimiters:
import org.apache.commons.text.WordUtils; public class WordUtilsExample { public static void main(String[] args) { String input = "*hello -world foo*bar"; // Define your custom word separators char[] delimiters = {'*', '-', ' '}; String capitalized = WordUtils.capitalizeFully(input, delimiters); System.out.println(capitalized); // Output: *Hello -World Foo*Bar } }
Note: This method will also convert all other letters to lowercase, so *HELLO becomes *Hello—which is usually what you want for "fully capitalized" words.
Option 2: Custom Regex Solution (No WordUtils Dependency)
If you don't want to use Apache Commons, you can replicate the capitalizeFully behavior with regex:
public static String customCapitalizeFully(String input) { if (input == null || input.isEmpty()) { return input; } // First convert all letters to lowercase, then capitalize after delimiters String lowerCaseInput = input.toLowerCase(); // Match start of string OR * / - / space, followed by a lowercase letter return lowerCaseInput.replaceAll("(^|[*\\-\\s])([a-z])", matcher -> matcher.group(1) + Character.toUpperCase(matcher.group(2).charAt(0)) ); }
How it works: It first normalizes all text to lowercase, then uses regex to find every position where a word starts (after *, -, space, or the start of the string) and capitalizes the following letter. Great for handling multiple consecutive special chars like **--hello.
Don't Forget the Dependency!
If you're using WordUtils, add this to your Maven pom.xml (or equivalent for Gradle):
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.10.0</version> <!-- Use the latest stable version --> </dependency>
内容的提问来源于stack exchange,提问作者willywonka15

