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

C语言:完善校验字符串是否为可提取数据的有效Markdown表格行的函数

C语言:完善校验字符串是否为可提取数据的有效Markdown表格行的函数

嗨,我看你现在写了个雏形函数,但目前只能判断固定表头,局限性太大啦。咱们得把它改成通用的,能准确识别出哪些是可以提取数据的有效表格行,排除表头、分隔线和空行。

先明确咱们的目标:函数接收一行字符串,只要这行是有实际数据的表格行就返回true,如果是表头、表头下面的分隔线、空表格行(只有竖线和空格)就返回false。

我给你一步步完善这个函数,先理清楚思路,再写代码:

首先得处理几个关键判断场景

咱们要先搞定三个需要排除的情况:

  • 空表格行:比如| | | |或者啥内容都没有的行
  • 表头分隔线行:就是那种全是-和:的行,比如| --- | :---: | ---: |
  • 固定表头行:就是你例子里的那行特定表头,这个可以保留硬编码判断,毕竟你的场景里表头是固定的

然后写辅助函数来拆分判断逻辑

直接把所有逻辑堆在check_line里会很乱,咱们拆成几个小辅助函数,清晰又好维护:

1. 先写个去除字符串两端空白的函数

因为输入的行可能带换行符或者首尾空格,这些会干扰判断,先把它们去掉:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// 去除字符串两端的空白(包括换行、空格、制表符)
char* trim(char* str) {
    // 跳过开头的空白
    while(isspace((unsigned char)*str)) str++;
    if(*str == 0) return str;
    // 从末尾往前找非空白字符
    char* end = str + strlen(str) - 1;
    while(end > str && isspace((unsigned char)*end)) end--;
    // 给字符串加结束符
    end[1] = '\0';
    return str;
}

2. 判断某一列是不是分隔线内容

分隔线的列里只会有-、:和空白,没有其他有效字符,咱们写个函数来判断:

// 判断单个列是不是分隔线(只包含-、:和空白)
int is_separator_column(const char* col) {
    while(*col != '\0') {
        if(!isspace((unsigned char)*col) && *col != '-' && *col != ':') {
            return 0; // 有其他字符,不是分隔线列
        }
        col++;
    }
    return 1;
}

3. 判断整行是不是分隔线行

遍历每一列,只要所有列都是分隔线内容,那这行就是表头和正文之间的分隔线:

// 判断整行是不是表格的分隔线行
int is_separator_line(char* line) {
    char* trimmed = trim(line);
    if(strlen(trimmed) == 0) return 0;
    if(trimmed[0] != '|') return 0; // 连表格行的基本格式都不符合,直接排除
    
    char* col_start = trimmed + 1; // 跳过开头的|
    char* col_end;
    while((col_end = strchr(col_start, '|')) != NULL) {
        *col_end = '\0'; // 临时截断,取出当前列
        if(!is_separator_column(col_start)) {
            *col_end = '|'; // 恢复原字符
            return 0;
        }
        *col_end = '|'; // 恢复原字符
        col_start = col_end + 1;
    }
    // 检查最后一列(如果行末尾没有|的情况)
    if(!is_separator_column(col_start)) {
        return 0;
    }
    return 1;
}

4. 判断是不是空表格行

空表格行里只有|和空白,没有任何实际数据:

// 判断是不是空的表格行(只有|和空白字符)
int is_empty_table_line(char* line) {
    char* trimmed = trim(line);
    if(strlen(trimmed) == 0) return 1;
    const char* p = trimmed;
    while(*p != '\0') {
        if(*p != '|' && !isspace((unsigned char)*p)) {
            return 0; // 有非空白非|的字符,不是空行
        }
        p++;
    }
    return 1;
}

最后完善核心的check_line函数

把上面的辅助函数整合起来,按顺序判断:

bool check_line(char* line) {
    puts(line); // 调试用的控制台输出
    
    // 先去掉末尾的换行符,避免干扰判断
    char* newline = strchr(line, '\n');
    if(newline != NULL) {
        *newline = '\0';
    }

    // 1. 先判断是不是空表格行,是就返回false
    if(is_empty_table_line(line)) {
        return false;
    }

    // 2. 判断是不是分隔线行,是就返回false
    if(is_separator_line(line)) {
        return false;
    }

    // 3. 判断是不是你指定的固定表头行,是就返回false
    char* trimmed_line = trim(line);
    if(strcmp(trimmed_line, "| Lebensmittel/Gericht | Gewicht in gr | kcal |") == 0) {
        return false;
    }

    // 剩下的情况就是有效数据行,返回true
    return true;
}

测试一下你的例子

用你给的测试用例跑一遍,结果完全符合预期:

  • | Lebensmittel/Gericht | Gewicht in gr | kcal | → 匹配表头,返回false
  • | -------------------- | ------------- | ---- | → 是分隔线,返回false
  • | Wildkräutersalat | 42 | 8 | → 有效数据行,返回true
  • | Rucola | 40 | 10 | → 有效数据行,返回true
  • | | | | → 空表格行,返回false
  • | Brot | 73 | 161 | → 有效数据行,返回true

这样就完美满足你的需求啦!如果以后表头变了,只需要修改那个硬编码的字符串就行,要是想做成通用的,把表头判断那部分去掉或者改成更灵活的逻辑就可以。

备注:内容来源于stack exchange,提问作者Simplicissimus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:19:39