【问题标题】:Break a long string into lines with proper word wrapping用正确的自动换行将长字符串分成几行
【发布时间】:2012-05-28 23:08:00
【问题描述】:
 String original = "This is a sentence.Rajesh want to test the application for the word split.";
 List matchList = new ArrayList();
 Pattern regex = Pattern.compile(".{1,10}(?:\\s|$)", Pattern.DOTALL);
 Matcher regexMatcher = regex.matcher(original);
 while (regexMatcher.find()) {
     matchList.add(regexMatcher.group());
 }
 System.out.println("Match List "+matchList);

我需要将文本解析为长度不超过 10 个字符的行数组,并且在行尾不应有断字。

我在我的场景中使用了以下逻辑,但是如果行尾有中断,它会在 10 个字符后解析到最近的空格

例如:实际的句子是“这是一个句子。Rajesh 想要测试应用程序的单词拆分。”但是在逻辑执行之后它得到如下。

匹配列表[这是一个,nce.Rajesh,想要,测试,应用,对于,单词,拆分。]

【问题讨论】:

  • 假设你想在 Groovy 中使用这个?除了标签之外,您没有提到 Groovy...
  • 你的意思是第10个字符不应该是?如果是空格呢?
  • 如果单词本身长度超过 10 个字符会怎样?是不是应该中间分开?例如,"quickbrownfoxjumpsoverthelazydog" 是否应该变为 {"quickbrown","foxjumpsov", "erthelazyd", "og"}?
  • 我不清楚你希望输出是什么 - 你能指定你希望你的例句如何分割吗?
  • @amaidment 我的要求是我需要将 1 行中的字符数限制为小于或等于 100 个字符而不破坏单词。如果单词在 100 字符的末尾是打破我们需要在下一行添加这个词。

标签: java regex matcher


【解决方案1】:

好的,所以我已经成功地完成了以下工作,最大行长为 10,但也正确分割了超过 10 的单词!

String original = "This is a sentence. Rajesh want to test the applications for the word split handling.";
List matchList = new ArrayList();
Pattern regex = Pattern.compile("(.{1,10}(?:\\s|$))|(.{0,10})", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(original);
while (regexMatcher.find()) {
  matchList.add(regexMatcher.group());
}
System.out.println("Match List "+matchList);

这是结果:

This is a 
sentence. 
Rajesh want 
to test 
the 
applicatio
ns word 
split 
handling.

【讨论】:

  • 如果你想包含换行符,那么:"(.{1,10}(?:\\s\\n|$))|(.{0,10})"跨度>
  • 使用正则表达式真是太好了!但是很难在断词之间添加'-'......
  • 对不起,我不明白?
  • This is a sentence.Rajesh want to test the applicati-ons word split handling.
【解决方案2】:

这个问题在某些时候被标记为 Groovy。假设 Groovy 答案仍然有效,并且您不担心保留多个空格(例如 ' '):

def splitIntoLines(text, maxLineSize) {
    def words = text.split(/\s+/)
    def lines = ['']
    words.each { word ->
        def lastLine = (lines[-1] + ' ' + word).trim()
        if (lastLine.size() <= maxLineSize)
            // Change last line.
            lines[-1] = lastLine
        else
            // Add word as new line.
            lines << word
    }
    lines
}

// Tests...
def original = "This is a sentence. Rajesh want to test the application for the word split."

assert splitIntoLines(original, 10) == [
    "This is a",
    "sentence.",
    "Rajesh",
    "want to",
    "test the",
    "application",
    "for the",
    "word",
    "split."
]
assert splitIntoLines(original, 20) == [
    "This is a sentence.",
    "Rajesh want to test",
    "the application for",
    "the word split."
]
assert splitIntoLines(original, original.size()) == [original]

【讨论】:

    【解决方案3】:

    我避免使用正则表达式,因为它不会减轻重量。此代码自动换行,如果单个单词超过 10 个字符,则将其中断。它还负责处理多余的空白。

    import static java.lang.Character.isWhitespace;
    
    public static void main(String[] args) {
      final String original =
        "This is a sentence.Rajesh want to test the application for the word split.";
      final StringBuilder b = new StringBuilder(original.trim());
      final List<String> matchList = new ArrayList<String>();
      while (true) {
        b.delete(0, indexOfFirstNonWsChar(b));
        if (b.length() == 0) break;
        final int splitAt = lastIndexOfWsBeforeIndex(b, 10);
        matchList.add(b.substring(0, splitAt).trim());
        b.delete(0, splitAt);
      }
      System.out.println("Match List "+matchList);
    }
    static int lastIndexOfWsBeforeIndex(CharSequence s, int i) {
      if (s.length() <= i) return s.length();
      for (int j = i; j > 0; j--) if (isWhitespace(s.charAt(j-1))) return j;
      return i;
    }
    static int indexOfFirstNonWsChar(CharSequence s) {
      for (int i = 0; i < s.length(); i++) if (!isWhitespace(s.charAt(i))) return i;
      return s.length();
    }
    

    打印:

    Match List [This is a, sentence.R, ajesh, want to, test the, applicatio, n for the, word, split.]
    

    【讨论】:

    • 我的要求是我需要将 1 行中的字符数限制为小于或等于 100 个字符而不破坏单词。如果 100 字符结尾的单词是破坏我们需要在下一行添加这个词
    猜你喜欢
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2013-05-13
    • 2010-12-13
    • 1970-01-01
    相关资源
    最近更新 更多