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

Java中如何使用TelnetClient解析SQLCI查询的原始返回结果

Java解析SQLCI固定宽度返回结果的解决方案

你遇到的本质是固定宽度格式化表格的解析问题,这类表格不是用分隔符区分字段,而是靠固定列宽对齐,因此不能直接按空格拆分内容。正确的处理思路是先通过表头下方的-分隔线计算每一列的坐标区间,再按区间截取内容,即可完美处理值含空格、空值的场景。

实现步骤

  1. 从返回结果中分离表头区和数据区
  2. 提取表头中所有全是-和空格的分隔线行,拼接为完整的分隔线总串
  3. 遍历分隔线总串,记录每一段连续-的起止坐标,作为对应列的截取范围
  4. 拼接表头的所有文本行,按列范围截取得到表头字段数组
  5. 拼接单条数据的所有行,按列范围截取得到对应的值数组

完整实现代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class SqlciParser {
    public static void main(String[] args) {
        String responeExample = 
                "CLI_IDC        CLI_VRT  CLI_IND_PER_EMP  CLI_TIP  CLI_CIC       CLI_COD_EST\n" +
                "-------------  -------  ---------------  -------  ------------  -----------\n" +
                "CLI_APE_PTN                CLI_APE_MTN                CLI_NOM\n" +
                "-------------------------  -------------------------  -------------------------\n" +
                "CLI_IND_SEX  CLI_COD_ACV  CLI_COD_EJE   CLI_COD_ECV  CLI_FEC_NAC\n" +
                "-----------  -----------  ------------  -----------  -----------\n" +
                "CLI_NOM_FTS                               CLI_COD_OFI  CLI_COD_PLN\n" +
                "----------------------------------------  -----------  -----------\n" +
                "CLI_COD_TIP_BCA  CLI_COD_SOC_ECO  CLI_IND_CNV  CLI_RTA\n" +
                "---------------  ---------------  -----------  ---------------------\n" +
                "CLI_COD_STO  CLI_PDO_STO\n" +
                "-----------  -----------\n" +
                "\n" +
                "005752983      0        P                CL           98707514  VIG\n" +
                "NO TOCAR                   TDM                        CELULA\n" +
                "M            95001        RFERNAS       SOL           1990-01-01\n" +
                "                                          090\n" +
                "PP                                N                            .0000\n" +
                "\n";

        // 1. 分离表头和数据
        String[] headersAndValues = responeExample.split("\n\n");
        String[] headerLines = headersAndValues[0].split("\n");
        String[] dataLines = headersAndValues[1].split("\n");

        // 2. 拼接分隔线总串、表头文本总串
        StringBuilder separatorSb = new StringBuilder();
        StringBuilder headerTextSb = new StringBuilder();
        for (String line : headerLines) {
            if (line.matches("^[- ]+$")) { // 匹配分隔线行
                separatorSb.append(line);
            } else {
                headerTextSb.append(line);
            }
        }
        String separatorLine = separatorSb.toString();
        String headerTextLine = headerTextSb.toString();

        // 3. 计算每列的起止坐标
        List<int[]> columnRanges = new ArrayList<>();
        int start = -1;
        for (int i = 0; i < separatorLine.length(); i++) {
            if (separatorLine.charAt(i) == '-' && start == -1) {
                start = i;
            } else if (separatorLine.charAt(i) != '-' && start != -1) {
                columnRanges.add(new int[]{start, i});
                start = -1;
            }
        }
        if (start != -1) { // 处理最后一列
            columnRanges.add(new int[]{start, separatorLine.length()});
        }

        // 4. 解析表头数组
        String[] headers = new String[columnRanges.size()];
        for (int i = 0; i < columnRanges.size(); i++) {
            int[] range = columnRanges.get(i);
            int endIdx = Math.min(range[1], headerTextLine.length());
            headers[i] = headerTextLine.substring(range[0], endIdx).trim();
        }

        // 5. 拼接数据行总串
        StringBuilder dataSb = new StringBuilder();
        for (String line : dataLines) {
            dataSb.append(line);
        }
        String dataLine = dataSb.toString();

        // 6. 解析值数组
        String[] values = new String[columnRanges.size()];
        for (int i = 0; i < columnRanges.size(); i++) {
            int[] range = columnRanges.get(i);
            int endIdx = Math.min(range[1], dataLine.length());
            if (range[0] >= dataLine.length()) {
                values[i] = "";
            } else {
                values[i] = dataLine.substring(range[0], endIdx).trim();
            }
        }

        // 输出结果验证
        System.out.println("表头数量:" + headers.length);
        System.out.println("表头:" + Arrays.toString(headers));
        System.out.println("值:" + Arrays.toString(values));
        // 验证含空格的值和空值
        System.out.println("CLI_APE_PTN的值:" + values[Arrays.asList(headers).indexOf("CLI_APE_PTN")]);
        System.out.println("CLI_NOM_FTS的值:" + values[Arrays.asList(headers).indexOf("CLI_NOM_FTS")]);
    }
}

运行结果验证

  • 可以正确解析到含空格的值CLI_APE_PTN = NO TOCAR
  • 空值字段CLI_NOM_FTS会返回空字符串,不会错位
  • 所有字段和表头一一对应,不会出现长度不匹配的问题

多数据行扩展

如果返回结果包含多条数据,只需用\n\n拆分数据区,每个块单独按上述逻辑解析即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:09:03