You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从存储文件内容的ArrayList中获取每行单词的字符位置并忽略//注释内容?

解决方案:实现单词字符位置显示与注释忽略

首先,先帮你修正现有代码里的一个小问题:你在readFile方法里用了for (String item: list)嵌套while循环来输出行内容,这会导致第一次循环就把所有行输出完毕,后续的循环都不会执行。我们可以直接用一个for循环遍历行索引来处理每一行。

接下来分两步实现你需要的功能:

1. 忽略//及其之后的内容

我们可以写一个辅助方法,专门处理每行的注释,只保留//之前的有效内容:

private String removeComments(String line) {
    // 找到//的位置,如果存在就截取之前的部分,否则返回原行
    int commentIndex = line.indexOf("//");
    if (commentIndex != -1) {
        return line.substring(0, commentIndex).trim();
    }
    return line.trim();
}

这个方法会去掉注释,同时把行首尾的空格也去掉,避免后续处理空内容。

2. 拆分单词并计算字符位置

接下来,我们需要对处理后的每一行,拆分出每个单词,并计算每个单词的起始字符位置(按照你示例里的要求从1开始计数)。这里我们遍历行的字符,识别单词的边界(空格分隔),记录每个单词的起始位置:

private void printWordPositions(String line, int lineNumber) {
    int currentCharPos = 1; // 字符位置从1开始
    int wordStartPos = -1;
    char[] chars = line.toCharArray();
    
    for (int i = 0; i < chars.length; i++) {
        char c = chars[i];
        // 如果是非空格字符,且还没记录单词起始位置,就记录
        if (!Character.isWhitespace(c) && wordStartPos == -1) {
            wordStartPos = currentCharPos;
        } 
        // 如果是空格字符,且已经记录了单词起始位置,就输出单词
        else if (Character.isWhitespace(c) && wordStartPos != -1) {
            String word = line.substring(i - (currentCharPos - wordStartPos), i).trim();
            System.out.printf("Line %d, 字符位置%d, %s%n", lineNumber, wordStartPos, word);
            wordStartPos = -1;
        }
        currentCharPos++;
    }
    // 处理行末尾的最后一个单词
    if (wordStartPos != -1) {
        String word = line.substring(chars.length - (currentCharPos - wordStartPos)).trim();
        System.out.printf("Line %d, 字符位置%d, %s%n", lineNumber, wordStartPos, word);
    }
}

整合到你的代码中

现在把这些方法整合到你的Lex_functions类里,并修改readFile方法的输出逻辑:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

public class Lex_functions {
    ArrayList<String> list = new ArrayList<>();

    void readFile() throws FileNotFoundException {
        File f = new File("ab.txt");
        // 使用try-with-resources自动关闭流,避免资源泄漏
        try (FileReader fr = new FileReader(f);
             BufferedReader infile = new BufferedReader(fr)) {
            String line;
            while ((line = infile.readLine()) != null) {
                list.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

        // 遍历每一行,处理并输出
        for (int lineNum = 0; lineNum < list.size(); lineNum++) {
            String originalLine = list.get(lineNum);
            // 先处理注释
            String processedLine = removeComments(originalLine);
            // 只处理非空的行
            if (!processedLine.isEmpty()) {
                // 行号从1开始,符合你的示例格式
                printWordPositions(processedLine, lineNum + 1);
            } else {
                // 如果处理后是空行,可以选择输出或者跳过,这里保留输出提示
                System.out.printf("Line %d, 无有效内容%n", lineNum + 1);
            }
        }
    }

    private String removeComments(String line) {
        int commentIndex = line.indexOf("//");
        if (commentIndex != -1) {
            return line.substring(0, commentIndex).trim();
        }
        return line.trim();
    }

    private void printWordPositions(String line, int lineNumber) {
        int currentCharPos = 1;
        int wordStartPos = -1;
        char[] chars = line.toCharArray();

        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (!Character.isWhitespace(c) && wordStartPos == -1) {
                wordStartPos = currentCharPos;
            } else if (Character.isWhitespace(c) && wordStartPos != -1) {
                String word = line.substring(i - (currentCharPos - wordStartPos), i).trim();
                System.out.printf("Line %d, 字符位置%d, %s%n", lineNumber, wordStartPos, word);
                wordStartPos = -1;
            }
            currentCharPos++;
        }
        if (wordStartPos != -1) {
            String word = line.substring(chars.length - (currentCharPos - wordStartPos)).trim();
            System.out.printf("Line %d, 字符位置%d, %s%n", lineNumber, wordStartPos, word);
        }
    }

    // 测试主方法
    public static void main(String[] args) throws FileNotFoundException {
        Lex_functions lex = new Lex_functions();
        lex.readFile();
    }
}

测试效果

假设你的ab.txt内容是:

// This program should print the number 20.
program Twenty:
int a;
int b;

运行代码后,输出会是:

Line 1, 无有效内容
Line 2, 字符位置1, program
Line 2, 字符位置9, Twenty:
Line 3, 字符位置1, int
Line 3, 字符位置5, a;
Line 4, 字符位置1, int
Line 4, 字符位置5, b;

额外说明

  • 如果你的单词分隔符不只是空格(比如制表符),可以把Character.isWhitespace(c)换成更全面的判断,或者用正则表达式拆分单词,但上面的方法更直观,适合基础场景。
  • 字符位置的计算是严格按照从行首开始的字符数(包括空格),比如program Twenty:里,program占7个字符,后面有一个空格,所以Twenty:的起始位置是7+1+1=9(因为从1开始计数)。

内容的提问来源于stack exchange,提问作者Lilypad01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:57:39