【问题标题】:Reformatting source code with Text I/O使用文本 I/O 重新格式化源代码
【发布时间】:2013-08-26 12:34:30
【问题描述】:

我正在通过一本教科书自学 Java 编程。一个练习要求你编写一个重新格式化整个源代码文件的程序(使用命令行):

从此格式(下一行大括号样式):

public class Test
{
    public static void main(String[] args)
    {
    // Some statements
    }
}

到这种格式(行尾大括号样式):

public class Test {
    public static void main(String[] args) {
    // Some statements
    }
}

这是我目前的代码:

import java.io.*;
import java.util.*;

public class FOURTEENpoint12 {

public static void main(String[] args) throws IOException {

    if (args.length != 2) {
        System.out.println
                    ("Usage: java FOURTEENpoint12 sourceFile targetFile");
        System.exit(1);
    }

    File sourceFile = new File(args[0]);
    File targetFile = new File(args[1]);

    if (!sourceFile.exists()) {
        System.out.println("File does not exist");
        System.exit(2);
    }

    Scanner input = new Scanner(sourceFile);
    PrintWriter output = new PrintWriter(targetFile);

    String token;


    while (input.hasNext()) {
        token = input.next();
        if (token.equals("{"))
            output.println("\n{\n");
        else
            output.print(token + " ");

    }

    input.close();
    output.close();
}

}

我有两个问题:

  1. 我尝试了许多不同的 while 块,但无法得到接近书中要求的任何内容。我已经尝试过正则表达式、分隔符、标记数组的不同组合,但仍然很差。

  2. 本书要求您重新格式化单个文件,但该章从未解释如何执行此操作。它仅说明如何将文本重写到新文件中。所以我只是编写了程序来创建一个新文件。但我真的很想按照问题要求的方式去做。

如果有人可以帮助我解决这两个问题,它实际上会解决我在很多练习中遇到的许多问题。提前致谢。

【问题讨论】:

  • 恕我直言:您在多行上应用正则表达式,因此您应该在使用它之前将整个文件放在一个字符串中。另一个提示:您的正则表达式 { => \n{ 与它应该做的完全相反:)
  • Scanner 默认使用一个或多个空白字符的分隔符。由于这是可变的,因此您将无法准确恢复它。您可以将分隔符设置为\n,但您也可以使用Scanner.hasNextLine/nextLineBufferedReader。然后你会检查token.matches("\\s*{\\s*")

标签: java regex


【解决方案1】:

这可以通过一个简单的regular expression 来实现。

您想将) *any whitesplace character* { 替换为) {

在 java 正则表达式中,有一个预定义的正则表达式:\s,它匹配所有空白字符:[ \t\n\x0B\f\r]

在这里,您想将)\s*{ 替换为) {

为此,将整个文件加载到一个字符串中(下面称为input)并使用String#replaceAll(String regex, String replacement)

//Added the escape characters...
input.replaceAll("\\)\\s*\\{", ") {");

测试:

String input = "public static void main()    \n    {";
System.out.println(input.replaceAll("\\)\\s*\\{", ") {"));

输出:

public static void main() {

【讨论】:

    【解决方案2】:

    如果我正确阅读了您的问题,您所需要的只是跟踪上一行和当前行。既然你在学习,我就给你粗略的提纲:

    • 如果当前行只包含大括号和空格,则忘记 当前行,在上一行添加空格和大括号,并保持为上一行。

    • 否则将上一行写入输出,将当前行设置为 上一行。

    • 读取新的当前行并在上面重复,直到输入文件结束。

    尝试更改您的代码以匹配它,逐行阅读。

    您可以通过修剪和比较"{" 或使用正则表达式来检测行是否为{

    "^\\s*\\{\\s*$"(未经测试)。

    注意:这是最简单的版本,假设可移动是单独的一行。

    【讨论】:

      【解决方案3】:

      首先:hasNextLine()nextLine() 似乎更适合逐行阅读。

      然后考虑必须做什么。

      阅读:

      line = "    public static void main(String[] args)";
      

      阅读:

      line = "    {"
      

      写:

      public static void main(String[] args) {
      

      其他所有内容都必须复制。

      也许您想print(line) 而不是println(line) 并单独确定println()?也许你需要记住你刚刚做了什么boolean linePrintedWithoutLn = false;

      【讨论】:

        【解决方案4】:
           import java.io.*;
           import java.util.Scanner;
           public class ReformatinCode {
              public static void main(String[] args) throws Exception{
                File f1 = new File ("java8_19.txt");
                File f2 = new File("java8_19_result.txt");
        
                Scanner scr1 = new Scanner(f1);
                StringBuffer sb1 = new StringBuffer();
                PrintWriter pw1 = new PrintWriter(f2);
                while(scr1.hasNext()){
                    sb1.append(scr1.nextLine() + System.lineSeparator());
                }
                scr1.close();
        
                String output = format(sb1.toString());
                System.out.println(output);
                pw1.print(output);
                pw1.close();
            }
        
        public static String format(String s){
                String result ="";  
                result = s.replaceAll("\\\r\\n\\s\\{","\\{");
                return result;
            }
        
        }
        /* this is a working answer , notice that the code that needed to be   reformated is stored in the file "java8_19.txt"... and the file "java8_19_result.txt" will be created after running the code.... both will be in the workspace directory within the package folder
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-20
          • 2020-04-09
          • 2011-03-30
          • 2013-03-10
          相关资源
          最近更新 更多