C# stringbuilder中的逗号转义
我遇到了一个相当简单的问题,但我的知识非常有限。我有一个将现有数据库转换为CSV的程序;但是,许多字段包含逗号,我需要它们转义。我尝试了几件没有用的事情(在ObjectToCsvData下),所以如果您对所包含的代码片段有任何帮助,我将不胜感激C# stringbuilder中的逗号转义,c#,csv,C#,Csv,我遇到了一个相当简单的问题,但我的知识非常有限。我有一个将现有数据库转换为CSV的程序;但是,许多字段包含逗号,我需要它们转义。我尝试了几件没有用的事情(在ObjectToCsvData下),所以如果您对所包含的代码片段有任何帮助,我将不胜感激 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Re
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统集合;
运用系统反思;
排序的名称空间
{
公共静态类实用程序
{
公共静态字符串集合TOCSV(IList集合)
{
StringBuilder sb=新的StringBuilder();
for(int index=0;index
}公共静态类CSV实用性
{
//我改变了一些,因为我认为你应该继续工作
//在复制粘贴之前理解代码。但是基本前提是
//详情如下:
公共静态字符串CreateFromEnumerable(IEnumerable enumerable)
{
//创建(并存储)对生成器的引用。这应该
//可以传递,而不是在中创建一次性实例
//每种方法。
var sb=新的StringBuilder();
var i=0;//计数器
//迭代每个对象
IEnumerator枚举器=可枚举的.GetEnumerator();
while(枚举数.MoveNext())
{
//从枚举器中删除当前对象
var obj=枚举器。当前值;
//缓存属性列表
var properties=obj.GetType().GetProperties();
如果(i++==0)
{
//如果是第一项,请使用属性列表和
//输出标题列。
//注意构建器是如何作为参数传递的。
(某人,财产);
}
//每件物品都会像往常一样被丢弃。
//注意构建器是如何作为参数传递的。
添加数据(sb、属性、obj);
}
//以字符串形式返回最终结果
使某人返回字符串();
}
//从对象的属性生成标题
私有静态void AddHeading(StringBuilder sb,PropertyInfo[]属性)
{
//快速短路检查
if(properties==null | | properties.Length==0)返回;
//迭代属性
对于(var p=0;p0)
{
某人加上(“,”);
}
//添加属性名,必要时转义
sb.Append(EscapeValue(properties[p].Name));
}
//添加新行(此行已完成)
(某人);
}
//基于属性和对象本身构建一条线
私有静态void AddData(StringBuilder sb,PropertyInfo[]属性,对象obj)
{
//快速短路检查
if(properties==null | | properties.Length==0)返回;
if(Object.ReferenceEquals(obj,null))返回;
//迭代属性
对于(var p=0;p0)
{
某人加上(“,”);
}
//从原始对象获取属性的值
//另外,将其转换为字符串,以便我们可以使用它。
var val=properties[p].GetValue(obj).ToString();
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;
}
}