2

我找不到任何关于如何解析一串键/值 paris AKA 查询字符串的信息,如下所示:

FieldType="String"&FieldFormat="^[a-z0-9!#$%&'*+/=?^_`{|}~-]+$"

字段分隔符可能包含在值中,如上面的示例,这不能用作 Web 请求参数列表。

我发现了这个:在逗号分隔的项目列表上运行循环进度 4GL

entry()不关心数据是否在 qoutation 中。

= 编辑 =

所以我找到了一个不太理想的解决方案,我希望没有人需要模仿

DO jj=1 TO NUM-ENTRIES(curr,"&"):

            DEFINE VARIABLE pos AS INTEGER     NO-UNDO.
            ASSIGN 
                k   = entry( 1, ENTRY(jj,curr,"&"), "=")                
                v   = entry( 2, ENTRY(jj,curr,"&"), "=")
                pos = INDEX( curr,  k + "=" ).

            /* Check if this is a qouted value*/
            IF NUM-ENTRIES( SUBSTRING( curr, pos, ABS( INDEX(curr, "&", pos) - pos) ) ,'"') > 1 THEN 
                ASSIGN v = ENTRY( 2, SUBSTRING( curr, pos) , '"').  

end.

IF 语句是由噩梦构成的!

4

4 回答 4

1
define variable qryString as character no-undo.

define variable sep1 as character no-undo.
define variable sep2 as character no-undo.
define variable trimlist as character no-undo.

define variable sep1pos as integer no-undo.
define variable sep2pos as integer no-undo.

define variable part1 as character no-undo format "x(60)".
define variable part2 as character no-undo format "x(60)".

define variable name1 as character no-undo format "x(60)".
define variable name2 as character no-undo format "x(60)".

define variable valu1 as character no-undo format "x(60)".
define variable valu2 as character no-undo format "x(60)".

qryString = 'FieldType="String"&FieldFormat="^[a-z0-9!#$%&~'*+/=?^_`~{|}~~-]+$"'.

sep1 = '&'.
sep2 = '='.
trimlist = '"' + "'".

sep1pos = index( qryString, sep1 ).
part1 = substring( qryString, 1, sep1pos - 1 ).
part2 = substring( qryString, sep1pos + 1 ).

sep2pos = index( part1, sep2 ).
name1 = trim( substring( part1, 1, sep2pos - 1 ), trimlist ).
valu1 = trim( substring( part1, sep2pos + 1 ), trimlist ).

sep2pos = index( part2, sep2 ).
name2 = trim( substring( part2, 1, sep2pos - 1 ), trimlist ).
valu2 = trim( substring( part2, sep2pos + 1 ), trimlist ).

    display
      part1 skip
      part2 skip
      name1 skip
      valu1 skip
      name2 skip
      valu2 skip
     with
      side-labels
    .

(我在带引号的字符串中使用“~”转义了特殊字符,以便将其包含在程序中,而不是从您拥有的任何输入源中获取它。在现实生活中,qryString 可能没有嵌入到程序中。)

于 2015-06-04T16:05:15.320 回答
1

根据 Tom 和 TheMadDBA 的答案构建。

假设:第一个 & 将是我们想要拆分的那个。

define variable cQryString as character no-undo.
define variable iSplitIndex as integer no-undo.
define variable cType as character no-undo format "x(30)" label "  Type".
define variable cFormat as character no-undo format "x(30)" label "Format".

assign 
  cQryString = 'FieldType=String&FieldFormat="^[a-z0-9!#$%&~'*+/=?^_`~{|}~~-]+$"' 
  iSplitIndex = index(cQryString, "&") 
  cType = substring(cQryString, 1, iSplitIndex - 1)
  cFormat = substring(cQryString, iSplitIndex + 1, length(cQryString))
  cType = substring(cType, index(cType, "=") + 1, length(cType))
  cFormat = substring(cFormat, index(cFormat, "=") + 1, length(cFormat))
  .

assign cType = entry(2, cType, '"') when substring(cType, 1, 1) = '"'.
assign cFormat = entry(2, cFormat, '"') when substring(cFormat, 1, 1) = '"'.

display
  cType skip
  cFormat
with side-labels.
于 2015-06-05T12:19:11.550 回答
0

如果您知道键列表,则可以使用 INDEX 函数查找所有键名称的起始位置,并使用 SUBSTRING 来分离字符串。

display INDEX(<yourvar>,"&FieldFormat").

您还可以使用带有 NUM-ENTRIES 和 ENTRY 的额外选项来提供要使用的分隔符 ('"'),只要它不会出现在其他引号内。

于 2015-06-04T14:02:58.577 回答
0

我认为除非您想进行强力剖析,否则唯一考虑分隔符和引号的进度功能是 IMPORT。

我认为你必须搞乱流,但看看这个:

http://knowledgebase.progress.com/articles/Article/P112126

其中讨论了在字段中使用逗号导入 CSV。

我试过使用它,虽然这个测试有流超时问题,但它有点工作:

def var test1 as char initial 'FldTp="String"&FldFmt="^[az0-9!#$%&+-/=^]+$"'.
def var kvp as char extent 10 format "x(50)".
def stream test.
input-output stream test through 'cat -u' unbuffered.
put stream test test1 format "X(100)" skip(1). 
import stream test delimiter "=" kvp .

input-output stream test close.
display kvp with 1 column.

有趣的是,为了得到“想要的”结果,你需要打破“=”而不是“&”,因为引号跟在“=”后面。但是,如果您有一些引用的值和一些未引用的值,这将不起作用。

输出形式是:

┌────────────────────────────────────────────────────────────────────┐
│          kvp[1]: FldTp                                             │
│          kvp[2]: String                                            │
│          kvp[3]: &FldFmt                                           │
│          kvp[4]: ^[a-z0-9!#$%&+-/=^]+$                             │
│          kvp[5]:                                                   │
│          kvp[6]:                                                   │
│          kvp[7]:                                                   │
│          kvp[8]:                                                   │
│          kvp[9]:                                                   │
│         kvp[10]:                                                   │
└────────────────────────────────────────────────────────────────────┘

所以它正确地破坏了值,你只需要从字段 + 中删除“&”

于 2015-06-05T07:01:17.687 回答