Guava学习笔记 6. 字符串处理[Strings]

非常有用的字符串工具,包括分割、连接、填充等操作

本文简单介绍了一下Guava的一些字符串工具
本文参考自:
http://ifeve.com/google-guava-strings/
并添加了一些其他测试代码
— By Syahfozy

连接器 [Joiner]

用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦。如果字符串序列中含有 null,那连接操作会更难。Fluent 风格的 Joiner 让连接字符串更简单。

Joiner joiner = Joiner.on("; ").skipNulls();
return joiner.join("Harry", null, "Ron", "Hermione");

上述代码返回”Harry; Ron; Hermione”。另外,useForNull(String) 方法可以给定某个字符串来替换 null,而不像 skipNulls() 方法是直接忽略 null。

joiner = Joiner.on("; ").useForNull("null");
str = joiner.join("Harry", null, "Ron", "Hermione");

即这里的返回结果是Harry; null; Ron; Hermione

Joiner 也可以用来连接对象类型,在这种情况下,它会把对象的 toString() 值连接起来。

Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"

警告:joiner 实例总是不可变的。用来定义 joiner 目标语义的配置方法总会返回一个新的 joiner 实例。这使得 joiner 实例都是线程安全的,你可以将其定义为 static final 常量。

拆分器 [Splitter]

JDK 内建的字符串拆分工具有一些古怪的特性。比如,String.split 悄悄丢弃了尾部的分隔符。 问题:”,a,b,”.split(“,”) 返回?

  1. “”, “a”, “”, “b”, “”
  2. null, “a”, null, “b”, null
  3. “a”, null, “b”
  4. “a”, “b”
  5. 以上都不对

正确答案是 5:””, “a”, “”, “b”。只有尾部的空字符串被忽略了。 Splitter 使用令人放心的、直白的流畅 API 模式对这些混乱的特性作了完全的掌控。

        // 按单个字符拆分
        Iterable<String> strings = Splitter
                .on(',')
                .trimResults()
                .omitEmptyStrings()
                .split("foo,bar,,   qux");
        // [foo, bar, qux]

上述代码返回 Iterable,其中包含”foo”、”bar” 和”qux”。Splitter 可以被设置为按照任何模式、字符、字符串或字符匹配器拆分。

按字符匹配器拆分

        // 按字符匹配器拆分
        strings = Splitter
                .on(CharMatcher.whitespace())
                .trimResults()
                .omitEmptyStrings()
                .split("foo bar   qux,qq");
        // [foo, bar, qux,qq]
        System.out.println(strings);

按字符串拆分

        // 按字符串拆分
        strings = Splitter
                .on("ab")
                .trimResults()
                .omitEmptyStrings()
                .split("fooabbarabaux");
        // [foo, bar, aux]
        System.out.println(strings);
        // 按正则表达式拆分
        strings = Splitter
                .onPattern("\\/")
                .trimResults()
                .omitEmptyStrings()
                .split("foo/abb /ara b ");
        // [foo, abb, ara b]
        System.out.println(strings);
        
        strings = Splitter
                .on(Pattern.compile("\\."))
                .trimResults()
                .omitEmptyStrings()
                .split("foo.bar.qux");
        // [foo, bar, qux]
        System.out.println(strings);
        // 按固定长度拆分;最后一段可能比给定长度短,但不会为空
        strings = Splitter
                .fixedLength(2)
                .split("foo bar");
        // [fo, o , ba, r]
        System.out.println(strings);

拆分器工厂

方法描述范例
Splitter.on(char)按单个字符拆分Splitter.on(‘;’)
Splitter.on(CharMatcher)按字符匹配器拆分Splitter.on(CharMatcher.BREAKING_WHITESPACE)
Splitter.on(String)按字符串拆分Splitter.on(“,   “)
Splitter.on(Pattern) Splitter.onPattern(String)按正则表达式拆分Splitter.onPattern(“\r?\n”)
Splitter.fixedLength(int)按固定长度拆分;最后一段可能比给定长度短,但不会为空。Splitter.fixedLength(3)

拆分器修饰符

方法描述
omitEmptyStrings()从结果中自动忽略空字符串
trimResults()移除结果字符串的前导空白和尾部空白
trimResults(CharMatcher)给定匹配器,移除结果字符串的前导匹配字符和尾部匹配字符
limit(int)限制拆分出的字符串数量

如果你想要拆分器返回 List,只要使用 Lists.newArrayList(splitter.split(string)) 或类似方法。 警告:splitter 实例总是不可变的。用来定义 splitter 目标语义的配置方法总会返回一个新的 splitter 实例。这使得 splitter 实例都是线程安全的,你可以将其定义为 static final 常量。

字符匹配器 [CharMatcher]

在以前的 Guava 版本中,StringUtil 类疯狂地膨胀,其拥有很多处理字符串的方法:allAscii、collapse、collapseControlChars、collapseWhitespace、indexOfChars、lastIndexNotOf、numSharedChars、removeChars、removeCrLf、replaceChars、retainAllChars、strip、stripAndCollapse、stripNonDigits。 所有这些方法指向两个概念上的问题:

  1. 怎么才算匹配字符?
  2. 如何处理这些匹配字符?

为了收拾这个泥潭,我们开发了 CharMatcher。

直观上,你可以认为一个 CharMatcher 实例代表着某一类字符,如数字或空白字符。事实上来说,CharMatcher 实例就是对字符的布尔判断——CharMatcher 确实也实现了 Predicate——但类似” 所有空白字符” 或” 所有小写字母” 的需求太普遍了,Guava 因此创建了这一 API。

然而使用 CharMatcher 的好处更在于它提供了一系列方法,让你对字符作特定类型的操作:修剪 [trim]、折叠[collapse]、移除[remove]、保留[retain] 等等。CharMatcher 实例首先代表概念 1:怎么才算匹配字符?然后它还提供了很多操作概念 2:如何处理这些匹配字符?这样的设计使得 API 复杂度的线性增加可以带来灵活性和功能两方面的增长。

注:CharMatcher 只处理 char 类型代表的字符;它不能理解 0x10000 到 0x10FFFF 的 Unicode 增补字符。这些逻辑字符以代理对 [surrogate pairs] 的形式编码进字符串,而 CharMatcher 只能将这种逻辑字符看待成两个独立的字符。

参考使用代码:

        /**
         * 字符匹配器[CharMatcher]
         */
        String string = "\u0009666 and  sb ";
        // 	666 and  sb
        System.out.println(string);

        // 移除control字符
        String noControl = CharMatcher.javaIsoControl().removeFrom(string);
        // 666 and  sb
        System.out.println(noControl);

        // 去除两端的空格,并把中间的连续空格替换成单个空格
        String spaced = CharMatcher.whitespace().collapseFrom(string, ' ');
        //  666 and sb
        System.out.println(spaced);

        // 只保留数字字符
        String theDigits = CharMatcher.inRange('0', '9').retainFrom(string);
        // 666
        System.out.println(theDigits);

        // 用*号替换所有数字
        String noDigits = CharMatcher.inRange('0', '9').replaceFrom(string, "*");
        // 	*** and  sb
        System.out.println(noDigits);


        // 只保留数字和小写字母
        String lowerAndDigit = CharMatcher.inRange('0', '9').or(CharMatcher.inRange('a', 'z')).retainFrom(string);
        // 666andsb
        System.out.println(lowerAndDigit);

获取字符匹配器

CharMatcher 中的常量可以满足大多数字符匹配需求:

ANYNONEWHITESPACEBREAKING_WHITESPACE
INVISIBLEDIGITJAVA_LETTERJAVA_DIGIT
JAVA_LETTER_OR_DIGITJAVA_ISO_CONTROLJAVA_LOWER_CASEJAVA_UPPER_CASE
ASCIISINGLE_WIDTH

其他获取字符匹配器的常见方法包括:

方法描述
anyOf(CharSequence)枚举匹配字符。如 CharMatcher.anyOf(“aeiou”) 匹配小写英语元音
is(char)给定单一字符匹配。
inRange(char, char)给定字符范围匹配,如 CharMatcher.inRange(‘a’, ‘z’)

此外,CharMatcher 还有 negate()and(CharMatcher)or(CharMatcher) 方法。

使用字符匹配器

CharMatcher 提供了多种多样的方法操作 CharSequence 中的特定字符。其中最常用的罗列如下:

方法描述
collapseFrom(CharSequence,   char)把每组连续的匹配字符替换为特定字符。如 WHITESPACE.collapseFrom(string, ‘ ‘) 把字符串中的连续空白字符替换为单个空格。
matchesAllOf(CharSequence)测试是否字符序列中的所有字符都匹配。
removeFrom(CharSequence)从字符序列中移除所有匹配字符。
retainFrom(CharSequence)在字符序列中保留匹配字符,移除其他字符。
trimFrom(CharSequence)移除字符序列的前导匹配字符和尾部匹配字符。
replaceFrom(CharSequence,   CharSequence)用特定字符序列替代匹配字符。

所有这些方法返回 String,除了 matchesAllOf 返回的是 boolean。

字符集 [Charsets]

不要这样做字符集处理:

试试这样写:

Charsets 针对所有 Java 平台都要保证支持的六种字符集提供了常量引用。尝试使用这些常量,而不是通过名称获取字符集实例。

大小写格式 [CaseFormat]

CaseFormat 被用来方便地在各种 ASCII 大小写规范间转换字符串——比如,编程语言的命名规范。CaseFormat 支持的格式如下:

格式范例
LOWER_CAMELlowerCamel
LOWER_HYPHENlower-hyphen
LOWER_UNDERSCORElower_underscore
UPPER_CAMELUpperCamel
UPPER_UNDERSCOREUPPER_UNDERSCORE

CaseFormat 的用法很直接:

String lowerCamel = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, "CONSTANT_NAME");
        // constantName
System.out.println(lowerCamel);

我们 CaseFormat 在某些时候尤其有用,比如编写代码生成器的时候。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值