为什么这个函数不返回一个可以使用ListToArray或ValueList的字符串?

时间:2015-12-14 17:07:52

标签: coldfusion coldfusion-10 coldfusion-11

我在format.cfc组件中创建了一个函数,该函数返回一个没有任何HTML代码的字符串:

<cffunction name="RemoveHTML" access="public" returntype="string" output="false" hint="Returns a string without any html">
  <cfargument name="UserString" required="yes">
  <cfset var result = "#REReplaceNoCase(Canonicalize(ARGUMENTS.UserString,false,true),'<[^>]*(?:>|$)', '', 'ALL')#">
  <cfreturn result>
</cffunction>

我现在想要在每个空格处拆分字符串并将其转换为列表。所以我尝试使用ValueList()和ListToArray()但他们不喜欢从函数返回的值。

使用ValueList()我收到错误消息:

  

函数ValueList

不支持复杂构造

或者在使用ListToArray时出现此错误:

  

复杂对象类型无法转换为简单值

我基本上只是这样做:

<!--- ValueList() --->
<title>#ValueList(Application.Format.RemoveHTML(UserString = rsProduct.Title), ' ')#</title>

<!--- ListToArray() --->
<title>#ListToArray(Application.Format.RemoveHTML(UserString = rsProduct.Title), ' ')#</title>

如果我删除了ListToArray()或ValueList()函数,那么我会得到我所期望的 - 一个没有HTML的产品标题字符串。

那么为什么函数不返回一个字符串,即使它看起来像一个?或者我错过了一些完全明显的东西?

2 个答案:

答案 0 :(得分:5)

正如其他人在评论中指出的那样,ValueList旨在返回查询对象列中包含的值列表。它不适用于字符串值。

ListToArray将列表转换为数组。然后,您无法在HTML中输出数组。所以ListToArray工作正常,当您尝试在cfoutput中显示错误时,就会发生错误。

在CF中使用内置编码函数是个好主意,例如encodeForHTML。所以你可以这样做:

<title>#encodeForHTML(Application.Format.RemoveHTML(UserString = rsProduct.Title))#</title>

encodeForHTML,可以接受可选的布尔第二个参数(默认为false),以指示是否要规范化字符串。因此,您可能希望这样做,而不是在自定义Canonicalize函数中调用RemoveHTML。完成所有功能后,RemoveHTML而不是RemoveHTMLAndCanonicalize:)

更新

回应OP的评论。

要从“空格分隔”字符串中获取逗号分隔列表,您可以使用replace函数。类似的东西:

<title>#encodeForHTML(replace(RemoveHTML(rsProduct.Title), " ", ",", "all"))#</title>

您当然可以将replace放入自定义函数中,我只是演示它是如何工作的。

你需要注意,它会用逗号替换所有空格,所以如果你连续有2个或更多个空格,那么它会显示,,(取决于有多少个空格) 。要解决这个问题,你可以使用正则表达式:

<title>#encodeForHTML(reReplace(RemoveHTML(rsProduct.Title), " +", ",", "all"))#</title>

您还可以使用listChangeDelims reReplace的整数,因为它会忽略空元素。

<title>#encodeForHTML(listChangeDelims(RemoveHTML(rsProduct.Title), ",", " "))#</title>

就个人而言,我会使用正则表达式版本,因为它更强大,你需要将它包装在一个函数中,以保持视图的美观和干净。

答案 1 :(得分:1)

I think there are multiple ways to do this, consider below is my text

<cfset myText = "Samsung Galaxy Note 4"/>

first method by using simple replace function

<cfset firstSolution = replace(myText," ",",","all")/>
<cfdump var="#firstSolution#" />

Second method by using reReplace method

<cfset secondSolution = rEReplace(myText,"\s+",",","all")/>
<cfdump var="#secondSolution#" />

If I would be you I would have use second method cause if by any chance I have multiple spaces in my string then instead of getting multiple ',' I will get single ',' given string is used in the title of the page, I would not take any risk have incorrect title.