我无法找到关于如何解析一串键/值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是做噩梦的!
答案 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;”来自现场+