为什么这个函数不是 return 一个适用于 ListToArray 或 ValueList 的字符串?

Why does this function not return a string that will work ListToArray or ValueList?

我在 format.cfc 组件中创建了一个函数,其中 returns 一个没有任何 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>

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

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

Complex constructs are not supported with function ValueList

或者我在使用 ListToArray 时遇到此错误:

Complex object types cannot be converted to simple values

我基本上就是这样做的:

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

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

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

那么为什么函数不返回一个字符串,即使它看起来像一个字符串?还是我漏掉了一些显而易见的东西?

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

ListToArray 将列表转换为数组。然后你不能在你的 HTML 中输出一个数组。所以 ListToArray 工作正常,当您尝试在 cfoutput 中显示它时出现错误。

最好使用CF中的内置编码函数,例如encodeForHTML。所以你可以这样做:

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

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

更新

回应 OP 的评论。

要从 'space delimited' 字符串中获取逗号分隔列表,则可以使用 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>

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

我认为有多种方法可以做到这一点,考虑下面是我的文字

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

第一种方法,使用简单的替换功能

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

第二种方法使用reReplace方法

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

如果我是你,我会使用第二种方法,因为如果我的字符串中有多个空格,那么我将得到单个 ',' 而不是得到多个 ',' 标题中使用了给定的字符串页面的标题不正确,我不会冒任何风险。