【问题标题】:Java 13 Triple-quote Text Block *WITHOUT* newlinesJava 13 三引号文本块 *WITHOUT* 换行符
【发布时间】:2019-12-12 17:55:38
【问题描述】:

带有""" 分隔符的Java 13 多行文本块功能正变得广为人知。

但是我有一个反复出现的需求,我需要整个段落而不需要嵌入的换行符。

也就是说,下面的代码sn -p:

String paragraph =
    """
    aaaa bbbb cccc
    dddd eeee ffff
    gggg hhhh iiii
    """;
System.out.println(paragraph);

如您所料,产生以下内容:

aaaa bbbb cccc
dddd eeee ffff
gggg hhhh iiii

...这通常非常有用。但是在我的情况下,对于特别大的段落,我需要它来生成:

aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii

(....稍后再处理文本流。)

有没有办法为三引号功能建立“无换行符”参数?

【问题讨论】:

  • 想象一下输入大量文本,这些文本将成为 HTML 文档的后续部分,或者类似地流入(比如说)一个可调整大小的对话框。我想输入许多“行”的数据没有"line" + "line" + "line" 等,并且没有EOL 的出现。避免这种迟钝且难以维护的语法完全是""" 背后的重点。

标签: java string double-quotes


【解决方案1】:

此功能的设计者也意识到了这一要求(参见 JEP368 中的 'New escape sequences')。因此,对于 JDK 14 的最新早期访问版本,您可以使用尾随 \ 来转义行尾的新行:

public class Main {
    public static void main(String[] args) {
        String paragraph =
            """
            aaaa bbbb cccc \
            dddd eeee ffff \
            gggg hhhh iiii \
            """;
        System.out.println(paragraph);
    }
}

打印:

aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii

【讨论】:

  • 14,嗯?我想知道缩进的串联是如何工作的,或者是否所有的空白都被擦干净了?
  • 但这仍然需要修改现有的字符串输入,在这种情况下,这可能足以直接删除换行符。
  • 嗯,首先他们说能够按原样嵌入文字文本是一个如此重要的功能,它证明了语言更改的合理性,现在它自己获得了转义序列,我想知道,什么是优于将 "aaaa bbbb cccc "+"dddd eeee ffff "+"gggg hhhh iiii " 分别放在不同的行中……
  • @Holger 该功能已拆分为 2 个;文本块(又名多行字符串)和原始字符串文字(即原样字符串,待定)。这只是前者。请注意,其他转义符,例如 \n,仍然适用于文本块。
  • 但是现在我们有了readString,嵌入式资源也更容易处理。我从不想将整个段落集成到源代码中,只是 I/O 的东西很烦人。
【解决方案2】:

您可以使用自 Java-11 以来引入的 String.lines

String output = paragraph.lines().collect(Collectors.joining());

值得一提的是,这里是 JShell 执行两个不同代码块的屏幕截图:

【讨论】:

  • ...与String output = paragraph.replaceAll("[\n\r]", "");作用相同
  • 并且非解决方案(直到 JDK-14 修改允许 \s""" 块中)允许我将没有 EOL 的行与我确实想要硬返回的行混合(比如段落之间等)
【解决方案3】:

确实,在 Java 13 中找到一个好的答案并不容易(甚至不可能),但我认为 Jorn Vernee 在他的回复中优雅地解决了这个问题(Java 14 中的新转义序列提供了一个可接受的解决方案)。

扩展列出的几个问题:

  • Holger 提到“'文本块'功能不是很有说服力”。我见过很多“丑陋”的代码进行人工字符串连接,所以我认为这个功能肯定解决了一个问题。另一方面,我不得不同意这样的特性留有很大的滥用空间(如“让我们在 Java 代码中放入大量文本,因为现在我们可以很好地做到这一点!" - 见下一点)。
  • 最初的问题提到了“大段落”,这让我建议根本不要使用此功能,而是将该内容外部化到资源文件中。
  • 关于清晰度和某些方面“对读者来说并不明显,因此我们的语法具有非显而易见的含义”。这部分是正确的,并且需要一些阅读和实验,而目前可用的材料并不多。我发现了这个:Programmer's Guide To Text Blocks,它提供了很多例子。我还编写了一些示例,关于文本块的示例在这里:TextBlocks.java

(别忘了text blocks are in 'second preview' mode)。

【讨论】:

    【解决方案4】:

    paragraph.replaceAll("\\n","") 应该为您完成这项工作。

    【讨论】:

    • Intellij 现在处于某种崩溃循环中,因为我在行尾使用了转义字符。也许最好的是""" line line line """.replaceAll("\\n",""); 虽然现在无法验证。
    • 我想还有一个(次要)问题是在运行时而不是编译时处理,但这不是我的目的。
    • 这个解决方案也达不到JDK-14的\s能力。如果我想要几个没有换行符的段落,但它们之间有换行符怎么办。
    【解决方案5】:

    为什么不把它通过扫描仪拉出来:

       String strip(String multiline){
          var scanner = new java.util.Scanner(multiline);
          var text = scanner.next();
          while (scanner.hasNext()) text += " "+ scanner.next();
          return text;
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-14
      • 2021-01-13
      • 2018-02-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多