我正在上传电子表格并将电子表格列标题映射到我的数据库中。电子邮件列是唯一需要的列。在下面的StringB中,,,,
只是表示跳过/忽略了一列。
我的问题是:
我有一个文本字符串(StringA)来自一个电子表格,我需要在另一个文本字符串(StringB)中找到它匹配我的数据库(这不是真正的值,只是简单地说明我的问题所以希望这是明确)。
Stringa:YR,MNTH,ANNIVERSARIES,FIRSTNAME,LASTNAME,EMAIL,NOTES
StringB:,YEAR,,MONTH,LastName,Email,Comments
MNTH和MONTH故意不同;
excelColumnList = 'YR,MNTH,ANNIV,FIRST NAME,LAST NAME,EMAIL,NOTES';
mappedColumnList= ',YEAR,,MONTH,,First Name,Last Name,Email,COMMENTS';
mappedColumn= 'Last Name';
local.index = ListFindNoCase(mappedColumnList, mappedColumn,',', true);
local.returnValue = "";
if ( local.index > 0 )
local.returnValue = ListGetAt(excelColumnList, local.index);
writedump(local.returnValue); // dumps "EMAIL" which is wrong
我遇到的问题是当StringB以,
开头时返回的索引返回错误的索引值,后者会影响映射。如果StringB以单词开头,则该过程完美地运行。当StringB以,
开头时,是否有更好的方法来获取索引?
我也尝试使用listtoarray
然后使用arraytolist
来清理它,但索引仍然关闭,我无法可靠地向索引添加+1以识别列表中的正确项目。
另一方面,我正在考虑这个mappedColumnList = right(mappedColumnList,len(mappedColumnList)-1)
删除仍然抛出我的索引值的领先,
但是我可以通过在索引中加1来解释这一点,这看起来可靠乍一看。只是担心这是一种黑客攻击。
有什么建议?
https://cfdocs.org/listfindnocase
这是一个cfgist:https://trycf.com/gist/4b087b40ae4cb4499c2b0ddf0727541b/lucee5?theme=monokai
更新我使用编辑#1接受了答案。我还在这里添加了评论:Finding specific instance in a list when the list starts with a comma
如果它是第一个字符,则从列表中识别并删除“,”。
编辑:更改为while
循环以识别多个前导“,”s。
尝试:
while(left(mappedColumnList,1) == ",") {
mappedColumnList = right( mappedColumnList,(len(mappedColumnList)-1) ) ;
}
https://trycf.com/gist/64287c72d5f54e1da294cc2c10b5ad86/acf2016?theme=monokai
编辑2:甚至更好,如果你不介意回到Java(和一点Regex),你可以完全跳过循环。超级高效。
mappedColumnList = mappedColumnList.replaceall("^(,*)","") ;
然后完全放下while
循环。
https://trycf.com/gist/346a005cdb72b844a83ca21eacb85035/acf2016?theme=monokai
<cfscript>
excelColumnList = 'YR,MNTH,ANNIV,FIRST NAME,LAST NAME,EMAIL,NOTES';
mappedColumnList= ',,,YEAR,MONTH,,First Name,Last Name,Email,COMMENTS';
mappedColumn= 'Last Name';
mappedColumnList = mappedColumnList.replaceall("^(,*)","") ;
local.index = ListFindNoCase(mappedColumnList, mappedColumn,',', true);
local.returnValue = ListGetAt(excelColumnList,local.index,",",true) ;
writeDump(local.returnValue);
</cfscript>
正则表达式^(,*)
的解释:
^
=从字符串的开头开始。()
=捕获这组角色,*
=一个字面逗号和所有连续重复。所以^(,*)
说,从字符串的开头开始并捕获所有连续的逗号,直到到达下一个不匹配的字符。然后replaceall()
用空字符串替换那组匹配的字符。
编辑3:我在原来的答案中修正了一个拼写错误。我只使用一个列表。
writeOutput(arraytoList(listtoArray(mappedColumnList)))
将摆脱你的领先逗号,但这是因为它会在变成数组之前删除空元素。这会抛出索引,因为原始mappedColumnList
字符串中有一个空元素。后面的字符串函数将读取并索引该空元素。因此,为了保持索引的正常工作,您需要确保Excel和db列始终处于相同的顺序,或者您必须为每个列名创建某种映射,然后在你需要使用的字符串上执行ListGetAt()
。
默认情况下,许多CF列表函数会忽略空元素。为这些函数添加了一个标志,以便您可以禁用此行为。如果你有字符串,,1,2,3
默认情况下listToArray将考虑3个元素,但listToArray(listVar, ",", true)
将返回5,前两个为空字符串。 ListGetAt具有相同的“includeEmptyValues”标志,因此当代码设置为true时,代码应该一致地工作。