0

我有一个要传递给函数的 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' ,我需要一些可以搜索此字符串、找到名称参数并在其值周围加上单引号的东西。

编辑

我这样做的原因是因为在我对数组调用 serializeJSON 之后,它会生成以下内容(简称为快照):

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

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

<cfset x = replace(x, """", "", "all")>

然后我需要在字符串 vars 上加回单引号。

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

4

3 回答 3

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}# />
于 2012-07-14T11:50:25.173 回答
1

如果您必须使用正则表达式,那么这应该可以

reReplace(json, "\bname\b.*?:([^,]+)", "name:'\1'", "All")
于 2012-07-14T15:00:46.400 回答
0

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

因此,最好的办法是从一开始就确保它的格式良好,而不是事后修复它。

正如@Peter 所提到的,如果您可以控制字符串的创建,那么就从头开始吧。如果您从第三方获得它,请与他们联系并指出这一点,他们可能会修复它。

您可以随时使用JSONLint来验证您的字符串,以确保您做对了。

于 2012-07-15T08:05:12.450 回答