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

Java多行字符串截取:按指定行号与字符位置获取子串

Java多行字符串指定行位置截取子串解决方案

问题背景

需要实现方法public static String substring(String text, int line, int character),输入多行字符串后,返回从开头到指定零基行号、该行指定零基字符位置的子串。示例:

  • 输入字符串:
    hello
    world
    how
    are
    you?
    
  • 调用substring(text, 0, 2) → 返回"he"
  • 调用substring(text, 1, 3) → 返回"hello\nwor"(保留原字符串换行符格式)
  • 调用substring(text, 3, 0) → 返回"hello\nworld\nhow\n"

已有的两种方案存在明显缺陷:

  • 基于string.lines()拼接:会频繁创建新String对象,性能损耗大
  • 基于indexOf定位换行符:无法兼容Unix(\n)、Windows(\r\n)、旧Mac(\r)等多种换行格式

问题1:获取原字符串中对应位置的索引x

要得到string.substring(0, x)中的x值,需要遍历原字符串并兼容所有换行符,核心逻辑和代码实现如下:

核心逻辑

  1. 初始化变量:当前行号currentLine = 0,当前遍历位置pos = 0
  2. 逐字符遍历字符串:
    • 若currentLine等于目标行号line:计算当前行的末尾位置,返回pos + character和行末尾的较小值(避免字符位置超出当前行长度)
    • 若遇到换行符:
      • 若当前字符是\r且下一个字符是\n(Windows换行):pos加2,行号加1
      • 否则(\n或单独\r):pos加1,行号加1
    • 非换行符:pos直接加1
  3. 边界处理:若目标行号超过总行数,返回整个字符串的长度

代码实现

public static int getTargetIndex(String text, int line, int character) {
    int currentLine = 0;
    int pos = 0;
    int len = text.length();
    
    while (pos < len) {
        if (currentLine == line) {
            // 找到当前行的末尾位置
            int lineEnd = pos;
            while (lineEnd < len) {
                char c = text.charAt(lineEnd);
                if (c == '\n' || c == '\r') {
                    break;
                }
                lineEnd++;
            }
            // 返回字符位置和行末尾的较小值,避免越界
            return Math.min(pos + character, lineEnd);
        }
        
        char c = text.charAt(pos);
        if (c == '\r') {
            // 处理Windows换行符\r\n
            if (pos + 1 < len && text.charAt(pos + 1) == '\n') {
                pos += 2;
            } else {
                pos += 1;
            }
            currentLine++;
        } else if (c == '\n') {
            // 处理Unix换行符\n
            pos += 1;
            currentLine++;
        } else {
            pos += 1;
        }
    }
    
    // 目标行超出总行数,返回整个字符串长度
    return len;
}

问题2:更优的子串截取方法

最优方案是原字符串直接遍历定位+原生substring截取,也就是结合上面的索引计算方法,直接调用text.substring(0, getTargetIndex(text, line, character))。

优势

  1. 性能最优:仅遍历一次字符串,无额外String对象创建或拼接,避免了lines()流式处理的性能开销
  2. 全换行符兼容:支持\n、\r\n、\r所有常见换行格式
  3. 边界处理完善:能处理行号超出、字符位置超出当前行长度等异常场景

完整方法实现

public static String substring(String text, int line, int character) {
    int targetIndex = getTargetIndex(text, line, character);
    return text.substring(0, targetIndex);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:22:45