进度4gl OpenEdge解析键/值对字符串又称Query-String

时间:2015-06-04 13:48:18

标签: query-string string-parsing progress-4gl openedge 4gl

我无法找到关于如何解析一串键/值paris AKA查询字符串的任何内容,如下所示:

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

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

我发现了这个:running a loop on a comma delimited list of items progress 4GL

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

= EDIT =

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

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-statment是做噩梦的!

4 个答案:

答案 0 :(得分: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可能没有嵌入到程序中。 )

答案 1 :(得分:1)

从汤姆和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.

答案 2 :(得分:0)

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

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

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

答案 3 :(得分: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.

有趣的是,为了得到“理想的”结果,你需要打破“=”而不是“&amp;”因为引号遵循“=”。但是,如果你有一些引用和一些非引用的值,这将无效。

输出形式是:

┌────────────────────────────────────────────────────────────────────┐
│          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]:                                                   │
└────────────────────────────────────────────────────────────────────┘

因此它正确地破坏了值,您只需删除“&amp;”来自现场+