字符串生成器中的逗号转义

本文关键字:转义 字符串 | 更新日期: 2023-09-27 18:32:38

这是我遇到的一个相当简单的问题,但我的知识非常有限。我有一个程序可以将现有数据库转换为CSV;但是,许多字段都包含逗号,我需要它们进行转义。我已经尝试了几件事无济于事(在 ObjectToCsvData 下),因此对包含的代码段的任何帮助将不胜感激。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
namespace OfaSort
{
public static class Utility
{
    public static string CollectionToCsv(IList collection)
    {
        StringBuilder sb = new StringBuilder();
            for (int index = 0; index < collection.Count; index++)
            {
            object item = collection[index];
            if (index == 0)
            {
                sb.Append(ObjectToCsvHeader(item));
            }
            sb.Append(ObjectToCsvData(item));
            sb.Append(Environment.NewLine);
        }
        return sb.ToString();
    }
    public static string ObjectToCsvData(object obj)
    {
        /*if (obj == null)
        {
            throw new ArgumentNullException("obj", "value is null");
        }*/
        StringBuilder sb = new StringBuilder();
        Type t = obj.GetType();
        PropertyInfo[] pi = t.GetProperties();
        for (int index = 0; index < pi.Length; index++)
        {
            /*object oTest = pi[index].GetValue(obj, null);
            string str = oTest.ToString();
            sb.Append(str.CsvQuote());
            */
            sb.Append(pi[index].GetValue(obj, null));        
            if (index < pi.Length - 1)
            {
                sb.Append(",");
            }
        }
        return sb.ToString();
}
    public static string ObjectToCsvHeader(object obj)
    {
        /*if (obj == null)
        {
            throw new ArgumentNullException("obj", "value is null!");
        }*/
        StringBuilder sb = new StringBuilder();
        Type t = obj.GetType();
        PropertyInfo[] pi = t.GetProperties();
        for (int index = 0; index < pi.Length; index++)
        {
            sb.Append(pi[index].Name);
            if (index < pi.Length - 1)
            {
                sb.Append(",");
            }
        }
        sb.Append(Environment.NewLine);
        return sb.ToString();
    }
public static string CsvQuote(this string text)
{
    if (text == null)
    {
        return string.Empty;
    }
    bool containsQuote = false;
    bool containsComma = false;
    int len = text.Length;
    for (int i = 0; i < len && (containsComma == false || containsQuote == false); i++)
    {
        char ch = text[i];
        if (ch == '"')
        {
            containsQuote = true;
        }
        else if (ch == ',')
        {
            containsComma = true;
        }
    }
    bool mustQuote = containsComma || containsQuote;
    if (containsQuote)
    {
        text = text.Replace("'"", "'"'"");
    }
    if (mustQuote)
    {
        return "'"" + text + "'""; 
    }
    else
    {
        return text;
    }
}
}

}

字符串生成器中的逗号转义

public static class CsvUtility
{
    // I'm varying this a bit because I think you should still work at
    // understanding the code before copy-pasting. But the basic premise
    // is as follows:
    public static String CreateFromEnumerable(IEnumerable enumerable)
    {
        // create (and store) a reference to your builder. This should
        // be passed around instead of creating one-off instances within
        // each method.
        var sb = new StringBuilder();
        var i = 0; // counter
        // Iterate over each object
        IEnumerator enumerator = enumerable.GetEnumerator();
        while (enumerator.MoveNext())
        {
            // Crab current object from enumerator
            var obj = enumerator.Current;
            // Cache the list of properties
            var properties = obj.GetType().GetProperties();
            if (i++ == 0)
            {
                // if its the first item, use the properties list and
                // output the heading column.
                // Notice how the builder is passed as an argument.
                AddHeading(sb, properties);
            }
            // every item will them be dumped as usual.
            // Notice how the builder is passed as an argument.
            AddData(sb, properties, obj);
        }
        // Return the final result as a string
        return sb.ToString();
    }
    // Build a heading from the properties of the object
    private static void AddHeading(StringBuilder sb, PropertyInfo[] properties)
    {
        // quick short-circuit check
        if (properties == null || properties.Length == 0) return;
        // iterate over the properties
        for (var p = 0; p < properties.Length; p++)
        {
            // if it's not the first property add a comma
            if (p > 0)
            {
                sb.Append(",");
            }
            // add the property name, escaping as necessary
            sb.Append(EscapeValue(properties[p].Name));
        }
        // add a new line (this line is complete)
        sb.AppendLine();
    }
    // Build a line based on the properties and the object itself
    private static void AddData(StringBuilder sb, PropertyInfo[] properties, Object obj)
    {
        // quick short-circuit check
        if (properties == null || properties.Length == 0) return;
        if (Object.ReferenceEquals(obj, null)) return;
        // iterate over the properties
        for (var p = 0; p < properties.Length; p++)
        {
            // if it's not the first property add a comma
            if (p > 0)
            {
                sb.Append(",");
            }
            // Get the value of the property from the original object
            // Also, convert it to a string so we can work with it.
            var val = properties[p].GetValue(obj).ToString();
            // add the value, escaping as necessary
            sb.Append(EscapeValue(val));
        }
        // add a new line (this line is complete)
        sb.AppendLine();
    }
    // Escape the value when necessary (per CSV standards)
    private static String EscapeValue(String value)
    {
        // quick short-circuit check
        if (String.IsNullOrEmpty(value)) return String.Empty;
        // If the value has a comma or a quote, we need to:
        // 1. Wrap the value in quotations
        // 2. Convert any existing quotations to double-quotations
        if (value.IndexOf(',') > -1 || value.IndexOf('"') > -1)
        {
            return String.Concat("'"", value.Replace("'"", "'"'""), "'"");
        }
        // No modification needed--return as-is.
        return value;
    }
}