Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对CSV特殊字符使用临时占位符是一种糟糕的做法吗?_Java_String_Csv - Fatal编程技术网

Java 对CSV特殊字符使用临时占位符是一种糟糕的做法吗?

Java 对CSV特殊字符使用临时占位符是一种糟糕的做法吗?,java,string,csv,Java,String,Csv,我正在处理许多不同格式的CSV文件,通常由普通用户手工编写,因此有很多、\n和\t等字段中的此类字符通常会在解析数据或生成新的CSV文件时产生问题,我通常会事先删除此类字符,但今天我在一个旧程序中发现以下代码: 它从结果集读取数据,并将每个值连接成一个字符串以形成一行,并处理分隔符(我们通常使用;),这段代码首先使用一个临时标志,如#tempselator#来分割每个字段,然后,当行完成时,应用一个replaceAll(“;”,“”)删除假分隔符,然后使用replaceAll(“#tempsel

我正在处理许多不同格式的CSV文件,通常由普通用户手工编写,因此有很多
\n
\t
等字段中的此类字符通常会在解析数据或生成新的CSV文件时产生问题,我通常会事先删除此类字符,但今天我在一个旧程序中发现以下代码:

它从
结果集
读取数据,并将每个值连接成一个
字符串
以形成一行,并处理分隔符(我们通常使用
),这段代码首先使用一个临时标志,如
#tempselator#
来分割每个字段,然后,当行完成时,应用一个
replaceAll(“;”,“”)
删除假分隔符,然后使用
replaceAll(“#tempselator#”,“;”)
形成有效行

事实上,我认为这是一种聪明的方法,可以避免对每个字段进行不必要的调用,并且只对整个行进行替换,但我认为这不是最好的方法,甚至不是最佳的方法

这真的是一种糟糕的做法吗?

这不是很糟糕,但也不是最好的方法

尽可能使用标准库。优秀的库,其中SuperCSV在支持CSV变体方面特别强大。这些库遵循最佳实践:在字段中使用特殊字符时会转义,或者对字段进行包装(通常使用引号)


如果CSV格式已经不正确,以至于字段中出现特殊字符,而没有进行适当的转义或换行,那么您就有一个数据清理问题,需要以其他方式解决。用临时占位符替换字符并不能解决这一问题,因为占位符同样会出现在字段内部和字段之间。

这种方法听起来不太优雅。你描述:

  • 对于每个输入字段,使用
    #tempselector#
  • 消除所有
  • 将所有出现的
    #tempselator#
    替换为
  • 这是三个步骤。不如改为:

  • 每个输入字段,去掉所有
  • 然后,使用
    将其连接到单个字符串上
  • 这是一个无步骤的过程。因此,更好

    下面是一些示例代码,以说明为什么这更简单:

    流样式:

    collection.stream().collect(Collectors.joining("#TempSeparator#"))
        .replace(";", "").replace("#TempSeparator#", ";");
    
    vs


    这是过度设计,一个不必要的人工制品

    至少使用常量字符:

    private static final char TEMP_SEPARATOR = '\u001f';
    
    • 该选项卡通常不会出现在文本
      \t
      中,它是一个理想的分隔符
    • 否则将使用控制字符:单位分隔符
      \u001f
      。可能是Unicode
    • 几乎无法使用的字符是
      \u0000
    优势在于其效率:

    s = s.replace(';', ',').replace('\u0000', ';');
    
    最好的解决方案仍然是替换单元格值本身的分隔符。 对于新行,可能必须这样做

    关于最后一个分隔符:IMHO制表符比分号更好,因为用空格替换制表符只会改变文本的w.r.t.空格。也就是说:不可能产生任何要求。喜欢的房间号码必须是楼层“;”号

    s = s.replace(';', ',').replace('\u0000', ';');