ColdFusion - 输出用于Highchart.js的JavaScript

时间:2012-07-14 08:55:48

标签: regex coldfusion highcharts

我有一个JSON字符串,我正在传递给一个函数。 该字符串是动态生成的,可能包含不同的“名称”参数。 看起来像这样(格式化更容易阅读):

<cfset x = "
    series: [
       {
           name:inbounds,
           data:
              [
                 [Date.UTC(2012,4,1),0],
                 [Date.UTC(2012,4,2),0],
                 [Date.UTC(2012,4,3),0]
              ]
       },
       {
           name:outbounds,
           data:
              [
                 [Date.UTC(2012,4,1),0],
                 [Date.UTC(2012,4,2),0],
                 [Date.UTC(2012,4,3),0]
              ]
       },
       {
           name:api,
           data:
              [
                 [Date.UTC(2012,4,1),441],
                 [Date.UTC(2012,4,2),441],
                 [Date.UTC(2012,4,3),443]
              ]
       },
       {
           name:excess,
           data:
              [
                 [Date.UTC(2012,4,1),0],
                 [Date.UTC(2012,4,2),0],
                 [Date.UTC(2012,4,3),0]
              ]
       }
    ] 
">

但是,我需要“name”参数的值才能在其周围加上单引号, 例如而不是name:inbounds,我需要name:'inbounds' 所以,我需要一些能够搜索这个字符串的东西,找到name参数并在其值周围加上单引号。

修改

我之所以这样做是因为我在一个数组上调用serializeJSON之后会生成以下内容(快照缩短):

[{"NAME":"Excess","DATA":[["Date.UTC(2012,5,1)",0],......

CF将所有内容都放在双引号中。我正在使用的Highcharts API不希望它像这样。 所以,我用

删除了双引号
<cfset x = replace(x, """", "", "all")>

然后我需要在字符串变量上添加单引号。

如果有更好的方法,我愿意接受它。

3 个答案:

答案 0 :(得分:4)

  

“字符串是动态生成的”

此时添加单引号。


(如果您遇到问题,请为其发布代码,我们可以解决该问题。)

之后使用正则表达式进行操作并不是理想的解决方案。


更新:现在我们了解了您实际在做什么......

以下是将CF数据转换为JS字符串以与Highcharts一起使用的代码概念验证。

这是一个部分解决方案 - 我还没有完成整个Highcharts API,下面的一些代码只实现了一半,有些位可能希望以不同方式完成,但是一般来说,它应该知道这是如何工作的。

如果您(和/或其他任何人)想要使用下面的代码并将其扩展为highcharts.cfc,我确信它对CFML社区有用......


代码:

<cffunction name="convertToHighchartsJs" returntype="String" output=false >
    <cfargument name="CfData" type="Struct" required />

    <cfif NOT StructKeyExists(Arguments.CfData,'Series')>
        <cfthrow message="Does not look like Highcharts data" />
    </cfif>

    <cfreturn "series:#serializeForHighcharts(Arguments.CfData.Series)#" />
</cffunction>


<cffunction name="serializeForHighcharts" returntype="String" output=false >
    <cfargument name="Data"       type="any"    required />
    <cfargument name="Name"       type="String" optional />
    <cfargument name="ParentName" type="String" optional />

    <cfset var JsString = "UNABLE TO SERIALIZE" />

    <cfif isStruct(Arguments.Data) >
        <cfsavecontent variable="JsString"><cfoutput><!---
            --->{<!---
                ---><cfloop item="local.CurItem" collection=#Arguments.Data#><!---
                    --->,#fixCase(CurItem)#:#serializeForHighcharts(Arguments.Data[CurItem],CurItem)#<!---
                ---></cfloop><!---
            --->}<!---
        ---></cfoutput></cfsavecontent>

        <cfset JsString = rereplace(JsString,'^\{,','{') />

    <cfelseif isArray(Arguments.Data) >

        <cfsavecontent variable="JsString"><cfoutput><!---
            --->[<!---
                ---><cfloop index="local.CurItem" array=#Arguments.Data#><!---
                    --->,#serializeForHighcharts(CurItem)#<!---
                ---></cfloop><!---
            --->]<!---
        ---></cfoutput></cfsavecontent>

        <cfset JsString = rereplace(JsString,'^\[,','[') />

    <cfelseif isSimpleValue(Arguments.Data) >

        <cfset var ShouldBeQuoted = false />

        <cfif StructKeyExists(Arguments,'Name')>
            <cfif ListFindNoCase('name,text,renderTo,type,color,layout,align,verticalalign',Arguments.Name)>
                <cfset ShouldBeQuoted = true />
            </cfif>

        <cfelseif StructKeyExists(Arguments,'ParentName') AND ListFindNoCase('categories',Arguments.ParentName) />
            <cfset ShouldBeQuoted = true />

        </cfif>

        <cfif ShouldBeQuoted >
            <cfset JsString = "'" & JsStringFormat(Arguments.Data) & "'" />
        <cfelse>
            <cfset JsString = Arguments.Data />
        </cfif>

    </cfif>

    <cfreturn JsString />
</cffunction>


<cffunction name="fixCase" returntype="String" output="false" access="private">
    <cfargument name="Text" type="String" required />

    <cfif NOT StructKeyExists(Variables,'Camels')>
        <cflock type="exclusive" name="regen_camels" timeout=10>
            <cfset Variables.Camels = StructNew() />
            <cfloop index="CurCamel" list="dataParser,dataURL,legendIndex,xAxis,yAxis">
                <cfset Variables.Camels[CurCamel] = CurCamel />
            </cfloop>
        </cflock>
    </cfif>

    <cfif StructKeyExists(Variables.Camels,Arguments.Text)>
        <cfreturn Variables.Camels[Arguments.Text] />
    <cfelse>
        <cfreturn Lcase(Arguments.Text) />
    </cfif>

</cffunction>

测试:

<cfset CfData =
    { 'Series':
        [
            { 'name':'inbounds'
            , 'data':
                [ ['Date.UTC(2012,4,1)',0]
                , ['Date.UTC(2012,4,2)',0]
                , ['Date.UTC(2012,4,3)',0]
                ]
            }
        ,
            { 'name':'outbounds'
            , 'data':
                [ ['Date.UTC(2012,4,1)',0]
                , ['Date.UTC(2012,4,2)',0]
                , ['Date.UTC(2012,4,3)',0]
                ]
            }
        ]
    } />

<cfset Expected = "series:[{name:'inbounds',data:[[Date.UTC(2012,4,1),0],[Date.UTC(2012,4,2),0],[Date.UTC(2012,4,3),0]]},{name:'outbounds',data:[[Date.UTC(2012,4,1),0],[Date.UTC(2012,4,2),0],[Date.UTC(2012,4,3),0]]}]" />


<cfset JsString = convertToHighchartsJs(CfData) />

<cfif JsString EQ Expected>
    <h1 style="color:green">Matches</h1>
<cfelse>
    <h1 style="color:red">different</h1>
</cfif>

<cfdump var=#{Received:JsString,Expected:Expected}# />

答案 1 :(得分:1)

如果你必须使用正则表达式,那么这应该工作

reReplace(json, "\bname\b.*?:([^,]+)", "name:'\1'", "All")

答案 2 :(得分:0)

我认为您问题的根本原因是变量x 中的字符串不是 JSON:它不符合JSON schema

所以在这里做的最好的事情,而不是试图在事后修复它,是为了确保它从一开始就很好。

当@Peter触及时,如果你控制了字符串的创建,那么就开始吧。如果你是从第三方获得的,请与他们联系并指出这一点,他们可能会解决它。

您可以使用JSONLint随时验证字符串,以确保正确执行。