我可以用番石榴将文本包装到给定宽度吗?

如何解决我可以用番石榴将文本包装到给定宽度吗?

| 我希望能够将长字符串包装成固定长度。在番石榴有办法吗? Apache Commons / Lang具有完全符合我需要的方法does0ѭ。番石榴是否有简单的方法来实现这一目标? 我知道我可以用ѭ1进行硬包装,但我想进行软包装。 更新:现在有一个悬赏这个问题。 显然,该功能在Guava中是不可用的,因此赏金会转到使用Guava中最简单(或最完整)和类似Guava的答案。除了Guava之外,没有库。     

解决方法

我们(Guava)强烈建议您使用ICU4J的
BreakIterator
类来处理在用户文本中查找断点的机制。     ,这是我自己的答案,以寻求灵感:
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,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,tortor augue rhoncus \" +
    \"leo,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,tortor
augue rhoncus leo,eget luctus nisl risus id erat. Nunc
tempor pretium gravida.
    ,为什么不使用番石榴来使用番石榴做更简单的事情? 实际上,
Splitter
类允许您使用
fixedLength()
方法进行硬包装,否则可以根据分隔符
char
String
拆分字符串。如果要使用番石榴,可以依靠
Splitter.on(\' \').split(string)
,但还必须将结果结合起来,具体取决于maxLength值,以\'\\ n \'替换\'\'。 无需使用番石榴,您也可以做自己想做的事。几行代码,没有依赖性。基本上,您可以使用commons-lang方法来简化它。这是我的包装方法:
public static String wrap(String str,int wrapLength) {
    int offset = 0;
    StringBuilder resultBuilder = new StringBuilder();

    while ((str.length() - offset) > wrapLength) {
        if (str.charAt(offset) == \' \') {
            offset++;
            continue;
        }

        int spaceToWrapAt = str.lastIndexOf(\' \',wrapLength + offset);
        // if the next string with length maxLength doesn\'t contain \' \'
        if (spaceToWrapAt < offset) {
            spaceToWrapAt = str.indexOf(\' \',wrapLength + offset);
            // if no more \' \'
            if (spaceToWrapAt < 0) {
                break;
            }
        }

        resultBuilder.append(str.substring(offset,spaceToWrapAt));
        resultBuilder.append(\"\\n\");
        offset = spaceToWrapAt + 1;
    }

    resultBuilder.append(str.substring(offset));
    return resultBuilder.toString();
}
是的,它与原始的commons-lang方法非常相似,但是我猜它更短,更容易并且根据您的需求。也许,此解决方案也比您的解决方案更有效,不是吗? 我已经用您的文字对其进行了测试,将我的结果与commons-lang结果进行了比较。似乎有效:
public static void main(String[] args) {

    String string = \"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,tortor augue rhoncus \"
            + \"leo,eget luctus nisl risus id erat. Nunc tempor pretium gravida.\";

    for (int maxLength = 2; maxLength < string.length(); maxLength++) {
        String expectedResult = WordUtils.wrap(string,maxLength);
        String actualResult = wrap(string,maxLength);

        if (!expectedResult.equals(actualResult)) {
            System.out.println(\"expectedResult: \\n\" + expectedResult);
            System.out.println(\"\\nactualResult: \\n\" + actualResult);
            throw new RuntimeException(
                    \"actualResult is not the same as expectedResult (maxLength:\"
                            + maxLength + \")\");
        }
    }
}
因此,问题是:您真的要使用番石榴来做到这一点吗?这种选择有什么好处?     ,我这样做很有趣,只是为了尽可能多地食用番石榴。尽管javanna的答案更好,
import java.util.Iterator;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;


public class SoftSplit {

    public static String softSplit(String string,int length) {
        //break up into words
        Iterable<String> words = Splitter.on(\' \').split(string);

        //an iterator that will return the words with appropriate
        //white space added
        final SoftSplitIterator softIter = new SoftSplitIterator(words,length);
        return Joiner.on(\"\").join(new Iterable<String>() {
            @Override
            public Iterator<String> iterator() {
                return softIter;
            }
        });
    }

    static class SoftSplitIterator implements Iterator<String> {
        private final int maxLength;
        private final PeekingIterator<String> words;
        private int currentLineLength;

        SoftSplitIterator(Iterable<String> words,int maxLength) {
            this.words = Iterators.peekingIterator(words.iterator());
            this.maxLength = maxLength;
        }

        @Override
        public boolean hasNext() {
            return words.hasNext();
        }

        @Override
        public String next() {
            String current = words.next();

            //strip leading spaces at the start of a line
            if(current.length() == 0 && currentLineLength == 0) {
                return \"\";
            }
            //nothing left after us
            if(!words.hasNext()) {
                return current;
            }
            String next = words.peek();

            if(currentLineLength + current.length() + next.length() < maxLength) {
                //this word and the next one won\'t put us over limit
                currentLineLength += current.length();
                return current + \" \";
            } else {
                //the next word will put us over the limit 
                //add a line break
                currentLineLength = 0;
                return current + \"\\n\";
            }
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }

    public static void main(String[] args) {
        String text = 
            \"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,eget luctus nisl risus id erat. Nunc tempor pretium gravida.\";
        System.out.println(softSplit(text,60));
    }
}
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?