【问题标题】:How do I replace unwanted commas in a comma delimited file in ColdFusion如何在 ColdFusion 中替换逗号分隔文件中不需要的逗号
【发布时间】:2025-12-16 15:15:02
【问题描述】:

我正在加载 CSV,并尝试在 MySQL 中插入内容。其中一个字段中有逗号,例如:

 "Jane Doe","Boston","None","Yes","No"
 "John Doe","New York","No garlic, onions, or nuts","Yes","No"
 "Mary Doe","New York","None","Yes","No"

我从读取文件开始:

<cffile action="read"file="/var/www/html/temp.csv" variable="datacsv"> 

然后我开始一个循环:

<cfloop index="index" list="#datacsv#" delimiters="#chr(13)#,#chr(10)#">
    <cfset item1 = Replace(listgetAt(index,1), """", "", "ALL")> #item1#<br>
    <cfset item2 = Replace(listgetAt(index,2), """", "", "ALL")> #item2#<br>
    <cfset item3 = Replace(listgetAt(index,3), """", "", "ALL")> #item3#<br>
    <cfset item4 = Replace(listgetAt(index,4), """", "", "ALL")> #item4#<br>
    <cfset item5 = Replace(listgetAt(index,5), """", "", "ALL")> #item5#<br>
</cfloop>

我的问题是,在第二项(John Doe)中,第三个字段中的逗号被解析为新字段。所以我要么需要找出我遗漏的原因,要么去掉任何字段中的逗号并用不同的字符替换它们。

【问题讨论】:

  • 你想对数据做什么?电子表格还是数据库?
  • 我看到你有智能引号。你的字符串会有智能引号还是这只是一个例子?
  • 数据库,智能引号只是示例。我只担心引号之间的逗号。
  • 有什么理由不能使用 MySQL 的bulk loading tool?它应该处理嵌入的逗号,并且通常比一次插入一行要快得多。
  • 请注意:“我知道如何在 CFML 中完成所有逻辑”并不意味着这是最好的方法,即使大部分已经完成。有时,学习一种新方法非常值得您花时间和精力。如果这是大数据,您可能会在应用程序端而不是 SQL 端进行验证,从而给您的方式带来巨大的瓶颈。

标签: coldfusion cfml railo lucee


【解决方案1】:

尝试使用此正则表达式将嵌入的逗号替换为破折号:

<cfscript>

    // CSV content
    csvContent = '"John Doe","New York","No garlic, onions, or nuts","Yes","No"';

    // Replace all comma in between with dash
    writeOutput(
        csvContent.replaceAll(
            ',(?!")|(?<!"),(?=[^"]*?"(?:,|\r?\n|\r|$))', '-'
        )
    );
</cfscript>

这里是GIST

编辑:

这可行,但它也会去除其中的任何 CR/LF。当我遍历我的项目时,我正在做:&lt;cfloop index="index" list="#csvContent#" delimiters="#chr(13)#,#chr(10)#"&gt;

您可以简单地使用 CR/LF(chr(13)chr(10)) 作为分隔符。 这是一个例子:

<!--- CSV content --->
<cfset csvContent = '"John Doe","New York","No garlic, onions, or nuts","Yes","No"'>

<!--- Replace all comma in between with dash --->
<cfset newCsvContent = csvContent.replaceAll(
    ',(?!")|(?<!"),(?=[^"]*?"(?:,|\r?\n|\r|$))', '-'
)>

<!--- Process records --->
<cfoutput>
    <cfloop list="#newCsvContent#" index="csvRow" delimiters="#chr(13)##chr(10)#">
        Column 1: #replace( csvRow.listGetAt( 1 ), """", "", "ALL")#<br>
        Column 2: #replace( csvRow.listGetAt( 2 ), """", "", "ALL")#<br>
        Column 3: #replace( csvRow.listGetAt( 3 ), """", "", "ALL")#<br>
        Column 4: #replace( csvRow.listGetAt( 4 ), """", "", "ALL")#<br>
        Column 5: #replace( csvRow.listGetAt( 5 ), """", "", "ALL")#<br>
        <br>
    </cfloop>
</cfoutput>

【讨论】:

  • 这行得通,但它也剥离了那里的任何 CR/LF。当我遍历我的项目时,我正在做:
  • 好的,我只是重新格式化了整个问题以使问题更清晰。希望有人可以提供帮助。谢谢
【解决方案2】:

使用&lt;cfhttp&gt; 而不是&lt;cffile&gt; 来读取文件。 name 属性为您提供了一个查询属性。 This document 声明 textQualifier 的默认值是双引号,但我还是会指定它。

【讨论】:

  • 刚刚试了一下,虽然 DUMP 完美解析了所有内容,但它仍在循环中中断。 Replace(listgetAt(index... ?
  • RE: 这行得通,但它也去掉了那里的任何 CR/LF mck - @Beginner 的例子对我来说很好。您能否创建一个重现该问题的可运行要点? trycf.com/gist/0510cfa439898f98b3d9b833d7c77bcd/…
  • 这里,看看这里,你会看到它在“No Garlic”处中断,它应该说“没有大蒜、洋葱或坚果”trycf.com/gist/e0c414ef9b5ef90706ee8e136a67ef06/…
  • @mck - 嗯...你没有实现他们在last example 中建议的 replaceAll 代码 :) 一旦你这样做了,它就可以正常工作了。
  • @Leigh 做到了...谢谢:-)