我可以用番石榴将文本换行到给定的宽度吗?

2022-09-01 23:01:04

我希望能够将长字符串包装成固定长度。有没有办法在番石榴做到这一点?

Apache Commons / LangWordUtils.wrap(String,length)的方法,它完全符合我的需求。番石榴有简单的方法可以做到这一点吗?

我知道我可以使用Splitter.fixedLength(int)做一个硬包装,但我想要一个软包装。


更新:现在这个问题有一个赏金。

显然,此功能在番石榴中不可用,因此赏金转到最简洁(或最完整)和类似番石榴的答案,该答案使用番石榴中的内容。除番石榴外,不允许使用任何酒。


答案 1

我们(番石榴)强烈建议您使用 ICU4J 的 BreakIterator 类来处理在用户文本中查找断点的机制。


答案 2

以下是我自己的答案,以寻求灵感:

public final class TextWrapper {

    enum Strategy implements WrapStrategy {
        HARD {

            @Override
            public String wrap(final Iterable<String> words, final int width) {
                return Joiner.on('\n')
                             .join(Splitter
                                    .fixedLength(width)
                                    .split(
                                        Joiner.on(' ').join(words)));
            }
        },
        SOFT {
            @Override
            public String wrap(final Iterable<String> words, final int width) {
                final StringBuilder sb = new StringBuilder();
                int lineLength = 0;
                final Iterator<String> iterator = words.iterator();
                if (iterator.hasNext()) {
                    sb.append(iterator.next());
                    lineLength=sb.length();
                    while (iterator.hasNext()) {
                        final String word = iterator.next();
                        if(word.length()+1+lineLength>width) {
                            sb.append('\n');
                            lineLength=0;
                        } else {
                            lineLength++;
                            sb.append(' ');
                        }
                        sb.append(word);
                        lineLength+=word.length();
                    }
                }
                return sb.toString();
            }
        }
    }

    interface WrapStrategy {
        String wrap(Iterable<String> words, int width);
    }

    public static TextWrapper forWidth(final int i) {
        return new TextWrapper(Strategy.SOFT, CharMatcher.WHITESPACE, i);
    }

    private final WrapStrategy  strategy;

    private final CharMatcher   delimiter;

    private final int           width;

    TextWrapper(final WrapStrategy strategy,
                final CharMatcher delimiter, final int width) {
        this.strategy = strategy;
        this.delimiter = delimiter;
        this.width = width;
    }

    public TextWrapper hard(){
        return new TextWrapper(Strategy.HARD, this.delimiter, this.width);
    }
    public TextWrapper respectExistingBreaks() {
        return new TextWrapper(
            this.strategy, CharMatcher.anyOf(" \t"), this.width);
    }

    public String wrap(final String text) {
        return this.strategy.wrap(
            Splitter.on(this.delimiter).split(text), this.width);
    }

}

示例用法 1:(80 个字符处硬包装)

TextWrapper.forWidth(80)
        .hard()
        .wrap("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
            "Maecenas porttitor risus vitae urna hendrerit ac condimentum " +
            "odio tincidunt.\nDonec porttitor felis quis nulla aliquet " +
            "lobortis. Suspendisse mattis sapien ut metus congue tincidunt. " +
            "Quisque gravida, augue sed congue tempor, tortor augue rhoncus " +
            "leo, eget luctus nisl risus id erat. Nunc tempor pretium gravida.");

输出:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor risu
s vitae urna hendrerit ac condimentum odio tincidunt. Donec porttitor felis quis
 nulla aliquet lobortis. Suspendisse mattis sapien ut metus congue tincidunt. Qu
isque gravida, augue sed congue tempor, tortor augue rhoncus leo, eget luctus ni
sl risus id erat. Nunc tempor pretium gravida.

示例用法 2:(在 60 个字符或之前软换行,保留现有换行符)

TextWrapper.forWidth(60)
    .respectExistingBreaks()
    .wrap("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
    "Maecenas porttitor risus vitae urna hendrerit ac condimentum " +
    "odio tincidunt.\nDonec porttitor felis quis nulla aliquet " +
    "lobortis. Suspendisse mattis sapien ut metus congue tincidunt. " +
    "Quisque gravida, augue sed congue tempor, tortor augue rhoncus " +
    "leo, eget luctus nisl risus id erat. Nunc tempor pretium gravida.");

输出:

Lorem ipsum dolor sit amet, consectetur adipiscing
elit.
Maecenas porttitor risus vitae urna hendrerit ac
condimentum odio tincidunt.
Donec porttitor felis quis nulla
aliquet lobortis. Suspendisse mattis sapien ut metus congue
tincidunt. Quisque gravida, augue sed congue tempor, tortor
augue rhoncus leo, eget luctus nisl risus id erat. Nunc
tempor pretium gravida.

推荐