CSV格式特殊字符转义处理

  • CSV是逗号分隔值(comama separated value)的缩写,也有一说是字符分隔值。因为分隔符也可以是其他字符。
  • 当csv某个字段中包含换行(CRLF)、双引号、逗号(分隔符)时,整个字段必须用双引号括起来。例如:
"aaa","b CRLF
bb","ccc" CRLF
zzz,yyy,xxx
  • 当csv某个字段用双引号括起来且字段中内容中还包含双引号时,必须在该引号前面再添加一个双引号进行转义。
"aaa","b""bb","ccc"
// gcc main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define  CSV_DELIM                 ","
#define  CSV_QUOTE                 "\""
#define  CSV_QUOTE_CHAR            '"'
#define  CSV_CRLF                  "\r\n"
#define  CSV_SPECIAL_CHARS         ",\"\r\n"

// 注意:
// 1, 这里假设escape buf足够大,不会出现溢出问题  
// 2, 并未考虑原始字符串就已经被双引号括起来的场景,如: "abc"这种可能已经不需要再加双引号了   
int escape_csv_string(char* escape_buf, const char* raw_data)
{
    int    found_special_char = 0;                    // 标识是否发现了双引号、逗号、CRLF中的任意一个特殊字符  
    const  char* first_non_quote_char = NULL;         // 记录“后面第一个字符的位置
    const  char* special_chars = CSV_SPECIAL_CHARS;

    int    buf_used_len = 0;
    const  char* tmp_val = raw_data;
    while (*tmp_val)
    {
        if (!found_special_char)                      // 只要发现一个特殊字符,就需要在该字段前后加". 后面就不需要再查找特殊字符了  
        {
            for (const char* c = special_chars; *c; ++c)
            {
                if (*tmp_val == *c)
                {
                    // 发现特殊字符,首先在整个字符串前面加一个",并设置标志位,以便整体遍历结束后在尾部也追加一个"   
                    strcat(escape_buf, CSV_QUOTE);
                    ++buf_used_len;
                    found_special_char = 1;
                    break;
                }
            }
        }

        // 如果特殊字符是",直接追加写进去两个""
        if (*tmp_val == CSV_QUOTE_CHAR)
        {
            if (NULL != first_non_quote_char)
            {
                // 发现"后,首先将上一个"之后到这个"之前的部分拷贝到buf中
                strncpy(escape_buf + buf_used_len, first_non_quote_char, tmp_val - first_non_quote_char);
                buf_used_len += tmp_val - first_non_quote_char;
                escape_buf[++buf_used_len] = '\0';
            }

            buf_used_len += 2;
            strcat(escape_buf, CSV_QUOTE);
            strcat(escape_buf, CSV_QUOTE);
            first_non_quote_char = NULL;    
        }
        else
        {
            // 记录第一个非"字符的位置
            if (NULL == first_non_quote_char)
                first_non_quote_char = tmp_val;
        }

        tmp_val++;
    }

    if (found_special_char)
    {
        if (NULL != first_non_quote_char)  // 最后一个字符是"
        {
            strcat(escape_buf, first_non_quote_char);
        }
        strcat(escape_buf, CSV_QUOTE);
    }
    else                                  // 说明字符串中没有特殊字符
    {
        strcat(escape_buf, raw_data);
    }
    return 0;
}


int main(int argc, char* argv[])
{
    while (1)
    {
        printf("\nplsese input a string:\n");
        char input[1024] = {0};
        scanf("%s", input);
        char output[1024] = {0};
        escape_csv_string(output, input);
        printf("After escape: s\n", output);
    }
    return 0;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Pandas读取CSV文件时,如果遇到特殊字符行,我们需要进行一些额外的操作才能成功读取这些数据。一种常见的特殊字符行是含有类似中文字符的行,这可能导致Pandas无法正确解析CSV文件,从而导致读取出错。 为了解决这个问题,我们可以在read_csv()函数中使用encoding参数指定文件的编码格式。例如,如果CSV文件的编码为UTF-8,我们可以使用如下代码读取文件: df = pd.read_csv('example.csv', encoding='utf-8') 另外,我们还可以使用quotechar参数指定CSV文件中的转义字符。例如,如果CSV文件中的转义字符为双引号,则可以使用如下代码读取文件: df = pd.read_csv('example.csv', quotechar='"') 如果以上方法无法解决特殊字符行的问题,我们还可以手动读取CSV文件,将特殊字符行排除掉,然后再使用Pandas读取剩余部分的数据。例如,可以使用Python自带的csv模块读取CSV文件: import csv with open('example.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) headers = next(reader) data = [row for row in reader if not is_special(row)] df = pd.DataFrame(data, columns=headers) 在以上代码中,is_special()函数是用来判断特殊字符行的自定义函数。如果某一行符合特殊字符行的条件,该行将被排除掉,不会被读入DataFrame中。 总之,Pandas读取CSV特殊字符行需要根据具体情况采取相应的解决方案,借助于encoding和quotechar参数以及自定义函数等方法,我们可以实现对各种特殊字符行的有效处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值