我有一个.csv文件(我无法控制数据),出于某种原因,它包含所有引号。
"Date","Description","Original Description","Amount","Type","Category","Name","Labels","Notes"
"2/02/2012","ac","ac","515.00","a","b","","javascript://"
"2/02/2012","test","test","40.00","a","d","c",""," "
我正在使用filehelpers,我想知道删除所有这些引号的最佳方法是什么?有没有什么说“如果我看到引号删除。如果找不到引号什么都没做”?
这会混淆数据,因为我会"\"515.00\""
有不必要的额外引号(特别是因为在这种情况下我想要的是十进制而不是字符串“。
我也不确定“javascript”是什么以及为什么会产生它,但这是来自我无法控制的服务。
修改 这就是我使用csv文件的方式。
using (TextReader textReader = new StreamReader(stream))
{
engine.ErrorManager.ErrorMode = ErrorMode.SaveAndContinue;
object[] transactions = engine.ReadStream(textReader);
}
答案 0 :(得分:9)
您可以在属性页面here上使用最佳描述的FieldQuoted
属性。请注意,该属性可以应用于任何FileHelpers字段(即使它键入Decimal
)。 (请记住,FileHelpers类描述了导入文件的规范。因此,当您将Decimal
字段标记为FieldQuoted
时,您在文件中说,此字段将被引用。< / em>的)
您甚至可以使用
指定引号是否可选[FieldQuoted('"', QuoteMode.OptionalForBoth)]
这是一个适用于您的数据的控制台应用程序:
class Program
{
[DelimitedRecord(",")]
[IgnoreFirst(1)]
public class Format1
{
[FieldQuoted]
[FieldConverter(ConverterKind.Date, "d/M/yyyy")]
public DateTime Date;
[FieldQuoted]
public string Description;
[FieldQuoted]
public string OriginalDescription;
[FieldQuoted]
public Decimal Amount;
[FieldQuoted]
public string Type;
[FieldQuoted]
public string Category;
[FieldQuoted]
public string Name;
[FieldQuoted]
public string Labels;
[FieldQuoted]
[FieldOptional]
public string Notes;
}
static void Main(string[] args)
{
var engine = new FileHelperEngine(typeof(Format1));
// read in the data
object[] importedObjects = engine.ReadString(@"""Date"",""Description"",""Original Description"",""Amount"",""Type"",""Category"",""Name"",""Labels"",""Notes""
""2/02/2012"",""ac"",""ac"",""515.00"",""a"",""b"","""",""javascript://""
""2/02/2012"",""test"",""test"",""40.00"",""a"",""d"",""c"","""","" """);
// check that 2 records were imported
Assert.AreEqual(2, importedObjects.Length);
// check the values for the first record
Format1 customer1 = (Format1)importedObjects[0];
Assert.AreEqual(DateTime.Parse("2/02/2012"), customer1.Date);
Assert.AreEqual("ac", customer1.Description);
Assert.AreEqual("ac", customer1.OriginalDescription);
Assert.AreEqual(515.00, customer1.Amount);
Assert.AreEqual("a", customer1.Type);
Assert.AreEqual("b", customer1.Category);
Assert.AreEqual("", customer1.Name);
Assert.AreEqual("javascript://", customer1.Labels);
Assert.AreEqual("", customer1.Notes);
// check the values for the second record
Format1 customer2 = (Format1)importedObjects[1];
Assert.AreEqual(DateTime.Parse("2/02/2012"), customer2.Date);
Assert.AreEqual("test", customer2.Description);
Assert.AreEqual("test", customer2.OriginalDescription);
Assert.AreEqual(40.00, customer2.Amount);
Assert.AreEqual("a", customer2.Type);
Assert.AreEqual("d", customer2.Category);
Assert.AreEqual("c", customer2.Name);
Assert.AreEqual("", customer2.Labels);
Assert.AreEqual(" ", customer2.Notes);
}
}
(注意,您的第一行数据似乎有8个字段而不是9个字段,因此我使用Notes
标记了FieldOptional
字段。
答案 1 :(得分:0)
这是一种方法:
string[] lines = new string[]
{
"\"Date\",\"Description\",\"Original Description\",\"Amount\",\"Type\",\"Category\",\"Name\",\"Labels\",\"Notes\"",
"\"2/02/2012\",\"ac\",\"ac\",\"515.00\",\"a\",\"b\",\"\",\"javascript://\"",
"\"2/02/2012\",\"test\",\"test\",\"40.00\",\"a\",\"d\",\"c\",\"\",\" \"",
};
string[][] values =
lines.Select(line =>
line.Trim('"')
.Split(new string[] { "\",\"" }, StringSplitOptions.None)
.ToArray()
).ToArray();
lines
数组表示样本中的行。必须将每个"
字符转义为C#字符串文字中的\"
。
对于每一行,我们首先删除第一个和最后一个"
字符,然后使用","
字符序列作为分隔符,将其拆分为子字符串集合。
请注意,如果您的值中自然出现"
个字符,则上述代码将无效。(即使已转义)。
修改:如果要从流中读取CSV,您需要做的就是:
var lines = new List<string>();
using (var streamReader = new StreamReader(stream))
while (!streamReader.EndOfStream)
lines.Add(streamReader.ReadLine());
上述代码的其余部分将完好无损。
修改:根据您的新代码,检查您是否正在寻找以下内容:
for (int i = 0; i < transactions.Length; ++i)
{
object oTrans = transactions[i];
string sTrans = oTrans as string;
if (sTrans != null &&
sTrans.StartsWith("\"") &&
sTrans.EndsWith("\""))
{
transactions[i] = sTrans.Substring(1, sTrans.Length - 2);
}
}
答案 2 :(得分:0)
我有同样的困境,当我将值加载到list对象中时,我会替换引号:
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LoadCSV();
}
private void LoadCSV()
{
List<string> Rows = new List<string>();
string m_CSVFilePath = "<Path to CSV File>";
using (StreamReader r = new StreamReader(m_CSVFilePath))
{
string row;
while ((row = r.ReadLine()) != null)
{
Rows.Add(row.Replace("\"", ""));
}
foreach (var Row in Rows)
{
if (Row.Length > 0)
{
string[] RowValue = Row.Split(',');
//Do something with values here
}
}
}
}
}
}
答案 3 :(得分:0)
这段代码可能对我开发的内容有所帮助:
using (StreamReader r = new StreamReader("C:\\Projects\\Mactive\\Audience\\DrawBalancing\\CSVFiles\\Analytix_ABC_HD.csv"))
{
string row;
int outCount;
StringBuilder line=new StringBuilder() ;
string token="";
char chr;
string Eachline;
while ((row = r.ReadLine()) != null)
{
outCount = row.Length;
line = new StringBuilder();
for (int innerCount = 0; innerCount <= outCount - 1; innerCount++)
{
chr=row[innerCount];
if (chr != '"')
{
line.Append(row[innerCount].ToString());
}
else if(chr=='"')
{
token = "";
innerCount = innerCount + 1;
for (; innerCount < outCount - 1; innerCount++)
{
chr=row[innerCount];
if(chr=='"')
{
break;
}
token = token + chr.ToString();
}
if(token.Contains(",")){token=token.Replace(",","");}
line.Append(token);
}
}
Eachline = line.ToString();
Console.WriteLine(Eachline);
}
}