1. 从字符串中移除特殊字符
有时候我们想从一个字符串中去掉所有非字母、非数字的字符,Guava 的 CharMatcher
提供了非常方便的方法。
比如下面这个例子,我们使用 retainFrom()
方法只保留字母和数字:
@Test
public void whenRemoveSpecialCharacters_thenRemoved(){
String input = "H*el.lo,}12";
CharMatcher matcher = CharMatcher.javaLetterOrDigit();
String result = matcher.retainFrom(input);
assertEquals("Hello12", result);
}
✅ 简单粗暴,一行搞定。
2. 移除非 ASCII 字符
如果你的数据中混入了一些非 ASCII 的字符(比如日文),而你只想保留英文或数字,可以用以下方式:
@Test
public void whenRemoveNonASCIIChars_thenRemoved() {
String input = "あhello₤";
String result = CharMatcher.ascii().retainFrom(input);
assertEquals("hello", result);
result = CharMatcher.inRange('0', 'z').retainFrom(input);
assertEquals("hello", result);
}
⚠️ 注意:inRange('0', 'z')
是个取巧但实用的方式,它会保留从 '0'
到 'z'
这个范围内的字符。
3. 移除不在指定字符集中的字符
更进一步,我们可以根据特定字符集来过滤字符。比如下面的例子中,我们只保留能被 “cp437” 字符集编码的字符:
@Test
public void whenRemoveCharsNotInCharset_thenRemoved() {
Charset charset = Charset.forName("cp437");
CharsetEncoder encoder = charset.newEncoder();
Predicate<Character> inRange = new Predicate<Character>() {
@Override
public boolean apply(Character c) {
return encoder.canEncode(c);
}
};
String result = CharMatcher.forPredicate(inRange)
.retainFrom("helloは");
assertEquals("hello", result);
}
💡 这里我们借助 CharsetEncoder
构造了一个 Predicate
来判断字符是否可被编码。
4. 校验字符串内容
CharMatcher
也可以用来做字符串校验,非常实用。
matchesAllOf()
:判断字符串中所有字符是否都满足条件matchesNoneOf()
:判断字符串中没有任何字符满足条件matchesAnyOf()
:判断字符串中是否有任意字符满足条件
来看个例子:
@Test
public void whenValidateString_thenValid(){
String input = "hello";
boolean result = CharMatcher.javaLowerCase().matchesAllOf(input);
assertTrue(result);
result = CharMatcher.is('e').matchesAnyOf(input);
assertTrue(result);
result = CharMatcher.javaDigit().matchesNoneOf(input);
assertTrue(result);
}
✅ 对于格式校验、输入验证这种场景,这个 API 真的很香。
5. 字符串修剪(Trim)
虽然 Java 自带的 trim()
只能去除首尾空格,但 CharMatcher
支持按自定义字符进行修剪:
@Test
public void whenTrimString_thenTrimmed() {
String input = "---hello,,,";
String result = CharMatcher.is('-').trimLeadingFrom(input);
assertEquals("hello,,,", result);
result = CharMatcher.is(',').trimTrailingFrom(input);
assertEquals("---hello", result);
result = CharMatcher.anyOf("-,").trimFrom(input);
assertEquals("hello", result);
}
🔧 常见用法:
trimLeadingFrom()
:修剪开头trimTrailingFrom()
:修剪结尾trimFrom()
:修剪两端
6. 字符串压缩(Collapse)
这个功能特别适合处理连续空格或特殊字符的情况,比如把多个空格合并为一个:
@Test
public void whenCollapseFromString_thenCollapsed() {
String input = " hel lo ";
String result = CharMatcher.is(' ').collapseFrom(input, '-');
assertEquals("-hel-lo-", result);
result = CharMatcher.is(' ').trimAndCollapseFrom(input, '-');
assertEquals("hel-lo", result);
}
📌 trimAndCollapseFrom()
是个好东西,自动帮你先 trim 再 collapse,省心。
7. 替换字符串中的字符
除了删除、保留,CharMatcher
也可以用来做字符替换:
@Test
public void whenReplaceFromString_thenReplaced() {
String input = "apple-banana.";
String result = CharMatcher.anyOf("-.").replaceFrom(input, '!');
assertEquals("apple!banana!", result);
result = CharMatcher.is('-').replaceFrom(input, " and ");
assertEquals("apple and banana.", result);
}
📌 replaceFrom()
支持替换成字符或字符串,非常灵活。
8. 统计字符出现次数
有时候我们需要统计某个字符或某类字符的出现次数,也可以用 CharMatcher
轻松搞定:
@Test
public void whenCountCharInString_thenCorrect() {
String input = "a, c, z, 1, 2";
int result = CharMatcher.is(',').countIn(input);
assertEquals(4, result);
result = CharMatcher.inRange('a', 'h').countIn(input);
assertEquals(2, result);
}
📊 用于日志分析、格式校验等场景非常实用。
9. 总结
通过这篇文章,我们介绍了 CharMatcher
的常用方法和实际应用场景。它在字符串处理方面非常强大,而且代码简洁、语义清晰。
如果你经常需要处理字符串的过滤、校验、替换等操作,Guava 的 CharMatcher
是一个非常值得掌握的工具类。