java字符串StringTokenizer在“//”之后无法识别令牌?
Posted
技术标签:
【中文标题】java字符串StringTokenizer在“//”之后无法识别令牌?【英文标题】:java string StringTokenizer doesn't recognize token after "//"? 【发布时间】:2021-03-03 00:02:56 【问题描述】:我正在编写一个代码,我只想在 java 文件中打印 cmets,当我有这样的 cmets 时它就可以工作
// a comment
但是当我有这样的评论时:
// /* cdcdf
它不会打印 "/* cdcdf" ,它只会打印一个空行 有人知道为什么会这样吗?
这是我的代码:
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);
【问题讨论】:
【参考方案1】:StringTokenizer 采用分隔符集合,而不是单个字符串分隔符。所以它在'/'字符上分裂。 “第二个”标记是两个初始“//”之间的空标记。
如果您只想要“//”之后的其余行,您可以使用:
if(line.startsWith("//"))
line = line.substring(2);
【讨论】:
如何在“//”字符串上拆分?因为这段代码不完整,我只是放了一小部分来理解问题,我实际上需要在“//”上进行拆分,因为有时有 cmet 是这样开头的“*/” 我不明白这个解决方案。它不工作..【参考方案2】:@jtahlborn 答案的补充。您可以通过迭代令牌来检查所有令牌: 例如:
...
StringTokenizer st1 = new StringTokenizer(line, "//");
while (st1.hasMoreTokens())
System.out.println("token found:" + st1.nextToken());
...
【讨论】:
如何在“//”字符串上拆分?因为这段代码不完整,我只是放了一小部分来理解问题,我实际上需要在“//”上进行拆分,因为有时有 cmet 是这样开头的“*/” 你真的想split
还是只想得到'//' 之后的剩余字符串?
我想要剩下的
但有时我有 */ 所以如果它只分裂 * 薄就会有问题【参考方案3】:
如果您按行阅读,则 StringTokenizer 在您的代码中不会做太多事情。试试这个,把 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 //
注意:尝试始终使用 trim() 删除字符串开头和结尾的所有 Blanc 空格。
按 // 分割线: líne.split("//")
更多一般用途,请查看:
Java - regular expression finding comments in code
【讨论】:
【参考方案4】:您可以通过查找//
的第一个位置来简化代码。 indexOf 可以很好地解决这个问题。您不需要标记,因为您真的只想要某个位置(或文本)之后的所有内容,您不需要将行分成多个部分。
如果您找到//
(indexOf
不会为“未找到”返回 -1),则使用 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 = line.indexOf("//");
if (commentStart != -1)
System.out.println(line.substring(commentStart));
// /* that's it
如果您不想打印 //
,只需将 2 添加到 commentStart
。
请注意,这种解析 cmets 的原始方法非常脆弱。如果您在自己的源代码上运行该程序,它也会很高兴地报告//");
,对于indexOf
的行。任何认真的寻找 cmets 的尝试都需要正确解析源代码。
编辑:如果您还想查找标记为/*
和*/
的其他 cmets,请对开始注释执行相同操作,然后在行尾查找结束注释。当所有评论都在一行上时,这将找到/* comment */
。当它看到开头的/*
时,它会查看该行是否以结尾的*/
结尾,如果是,则再次使用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 */
要为跨多行的 cmets 扩展此功能,您需要记住您是否处于多行注释中,以及是否继续打印 line
并检查结束 */
。
【讨论】:
太棒了,我实际上正在更改我所有的代码来做你所说的,但我有一个小问题,在我的代码中我也可以得到这样的评论 /* 评论 / ,我想出了如何找到 / 并查看它是否出现在 // 之前,但现在的问题是如何不打印 */ 最后以上是关于java字符串StringTokenizer在“//”之后无法识别令牌?的主要内容,如果未能解决你的问题,请参考以下文章
Java--字符串使用StringTokenizer来分割字符,由小写转大写,由大写转小写