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

vol*_*one 1 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>
Run Code Online (Sandbox Code Playgroud)

我现在想要在每个空格处拆分字符串并将其转换为列表.所以我尝试使用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>
Run Code Online (Sandbox Code Playgroud)

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

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

Joh*_*ish 5

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

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

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

<title>#encodeForHTML(Application.Format.RemoveHTML(UserString = rsProduct.Title))#</title>
Run Code Online (Sandbox Code Playgroud)

encodeForHTML,可以接受一个可选的布尔第二个参数(默认为false),以指示是否要规范化字符串.因此,您可能希望这样做而不是调用Canonicalize自定义RemoveHTML函数.毕竟你的函数调用RemoveHTMLRemoveHTMLAndCanonicalize:)

更新

回应OP的评论.

要从"空格分隔"字符串中获取逗号分隔列表,则可以使用该replace函数.就像是:

<title>#encodeForHTML(replace(RemoveHTML(rsProduct.Title), " ", ",", "all"))#</title>
Run Code Online (Sandbox Code Playgroud)

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

您需要注意,它将用逗号替换所有空格,因此如果您连续有2个或更多空格,那么它将显示,,(取决于空格的数量).要解决这个问题,您可以使用正则表达式,如下所示:

<title>#encodeForHTML(reReplace(RemoveHTML(rsProduct.Title), " +", ",", "all"))#</title>
Run Code Online (Sandbox Code Playgroud)

你也可以使用listChangeDelimsintead,reReplace因为它忽略了空元素.

<title>#encodeForHTML(listChangeDelims(RemoveHTML(rsProduct.Title), ",", " "))#</title>
Run Code Online (Sandbox Code Playgroud)

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