简体   繁体   English

java string StringTokenizer 无法识别“//”之后的标记?

[英]java string StringTokenizer doesn't recognize token after "//"?

i am writing a code where i want to print only comments in a java file , it worked when i have a comments like this我正在编写一个代码,我只想在 java 文件中打印注释,当我有这样的注释时它起作用了

// a comment

but when i have a comment like this :但是当我有这样的评论时:

// /* cdcdf

it will not print "/* cdcdf" , it only prints a blank line anyone know why this happens ?它不会打印 "/* cdcdf" ,它只会打印一个空行有人知道为什么会这样吗?

here is my code :这是我的代码:

package printC;

import java.io.*; 
import java.util.StringTokenizer;
import java.lang.String ;


public class PrintComments {
    

    public static void main(String[] args) {
        try {
            String line;
            BufferedReader br = new BufferedReader(new FileReader(args[0]));
            while ((line = br.readLine()) != null) {
                if  (line.contains("//") ) {
                     StringTokenizer st1 =  new StringTokenizer(line, "//"); 
                     if(!(line.startsWith("//"))) {
                         st1.nextToken();
                     }
                     System.out.println(st1.nextToken()); 
                }
            }   
        }catch (Exception e) {
            System.out.println(e);
        }       
    }
}

StringTokenizer takes a collection of delimiters, not a single string delimiter. StringTokenizer 需要一组定界符,而不是单个字符串定界符。 so it is splitting on the '/' char.所以它在'/'字符上分裂。 the "second" token is the empty token between the two initial "//". “第二个”标记是两个初始“//”之间的空标记。

If you just want the rest of the line after the "//", you could use:如果您只想要“//”之后的其余行,您可以使用:

if(line.startsWith("//")) {
  line = line.substring(2);
}

You can simplify the code by just looking for the first position of the // .您可以通过查找//的第一个位置来简化代码。 indexOf works fine for this. indexOf为此工作正常。 You don't need to tokenize as you really just want everything after a certain position (or text), you don't need to split the line into multiple pieces.您不需要标记,因为您真的只想要某个位置(或文本)之后的所有内容,您不需要将行分成多个部分。

If you find the // ( indexOf doesn't return -1 for "not found"), you use substring to only print the characters starting at that position.如果找到//indexOf不会为“未找到”返回 -1),则使用substring仅打印从该位置开始的字符。

This minimal example should do what you want:这个最小的例子应该做你想做的:

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


public class PrintComments {
    public static void main(String[] args) throws IOException {
        String line;    // comment
        BufferedReader br = new BufferedReader(new FileReader(args[0]));
        while ((line = br.readLine()) != null) {
            int commentStart = line.indexOf("//");
            if (commentStart != -1) {
                System.out.println(line.substring(commentStart));
            }
        } // /* that's it
    }
}

If you don't want to print the // , just add 2 to commentStart .如果您不想打印// ,只需将 2 添加到commentStart

Note that this primitive approach to parsing for comments is very brittle.请注意,这种解析注释的原始方法非常脆弱。 If you run the program on its own source, it will happily report //"); as well, for the line of the indexOf . Any serious attempt to find comments need to properly parse the source code.如果您在自己的源代码上运行该程序,它会很高兴地报告//");同样,对于indexOf的行。任何认真的查找注释的尝试都需要正确解析源代码。

Edit: If you want to look for other comments marked by /* and */ as well, do the same thing for the opening comment, then look for the closing comment at the end of the line.编辑:如果您还想查找由/**/标记的其他注释,请对开始注释执行相同的操作,然后在行尾查找结束注释。 This will find a /* comment */ when all of the comment is on a single line.当所有注释都在一行上时,这将找到一个/* comment */ When it sees the opening /* it looks whether the line ends with a closing */ and if so, uses substring again to only pick the parts between the comment markers.当它看到开头/*它会查看该行是否以结尾*/结尾,如果是,则再次使用substring仅选取注释标记之间的部分。

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


public class PrintComments {
    public static void main(String[] args) throws IOException {
        String line;    // comment
        BufferedReader br = new BufferedReader(new FileReader(args[0]));
        while ((line = br.readLine()) != null) {
            int commentStart;
            String comment = null;

            commentStart = line.indexOf("//");
            if (commentStart != -1) {
                comment = line.substring(commentStart + 2);
            }

            commentStart = line.indexOf("/*");
            if (commentStart != -1) {
                comment = line.substring(commentStart + 2);
                if (comment.endsWith("*/")) {
                    comment = comment.substring(0, comment.length() - 2);
                }
            }

            if (comment != null) {
                System.out.println(comment);
            }
        } // /* that's it
        /* test */
    }
}

To extend this for comments that span multiple lines, you need to remember whether you're in a multi-line comment, and if you are keep printing line and checking for the closing */ .要为跨越多行的注释扩展此功能,您需要记住您是否在多行注释中,以及是否继续打印line并检查结束*/

Additional to @jtahlborn answer.补充@jtahlborn 答案。 You can check all of the token by iterating token: eg:您可以通过迭代令牌来检查所有令牌:例如:

...
 StringTokenizer st1 =  new StringTokenizer(line, "//"); 
 while (st1.hasMoreTokens()){
        System.out.println("token found:" + st1.nextToken());
}
...

If you are reading per line, the StringTokenizer don't do much in your code.如果您正在阅读每一行,则 StringTokenizer 在您的代码中不会做太多事情。 Try this, change the content of if like this:试试这个,像这样改变 if 的内容:

if(line.trim().startWith("//")){//true only if líne start with //,aka: comment line
//Do stuff with líne
String cleanLine = line.trim().replace("//"," ");//to remove all // in line
String cleanLine = línea.trim().substring(2,línea.trim().lenght());//to remove only the first //
}

Note: try to always use the trim() to remove all Blanc spaces at begin and end of string.注意:尝试始终使用trim() 删除字符串开头和结尾处的所有Blanc 空格。

To split the líne per // use: líne.split("//")要按 // 拆分线路,请使用: líne.split("//")

For more general purpose,check out :对于更通用的用途,请查看:

Java - regular expression finding comments in code Java - 正则表达式在代码中查找注释

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM