如果您只有兩個分隔符,則此代碼是執行搜索的乾淨方式。它可以擴展到三個或更多的分隔符,但我可能會以不同的方式構造代碼。 (我會遍歷分隔符列表,讓我知道你是否需要這樣的代碼。)
此代碼的一個目的是最小化執行的字符串搜索次數。與每次查找後都搜索兩個分隔符相比,它足夠聰明,只需搜索一個。我相信這會使其性能不失明確 - 但我沒有做基準測試,而且我可能是錯的。一如既往,最佳解決方案將取決於數據的性質。
DEFINE VARIABLE v-edistring AS CHARACTER NO-UNDO.
DEFINE VARIABLE v-cnt AS INTEGER NO-UNDO.
DEFINE VARIABLE segment AS CHARACTER NO-UNDO.
DEFINE VARIABLE v-curpsn AS INTEGER NO-UNDO.
DEFINE VARIABLE v-idxplus AS INTEGER NO-UNDO.
DEFINE VARIABLE v-idxcolon AS INTEGER NO-UNDO.
DEFINE VARIABLE v-element AS CHARACTER NO-UNDO.
v-edistring = "STS++56+202:::DUE TO HOLIDAY1'STS++56+202:::DUE TO HOLIDAY2'STS++56+202:::DUE TO HOLIDAY3'".
DO v-cnt = 1 TO num-entries(v-edistring, "'") - 1 :
ASSIGN segment = string(entry(v-cnt, v-edistring, "'")).
MESSAGE "SEGMENT: " segment
VIEW-AS ALERT-BOX INFO BUTTONS OK.
/*
** Cleverness here....
** Find the first positions of each delimiter in the segment
**
** Then:
** Clip out an element of the segment up through the next nearest delim.
** Recalculate the next postion of that delimiter
** ... and loop
*/
v-curpsn = 1.
v-idxplus = INDEX(segment, "+", v-curpsn).
v-idxcolon = INDEX(segment, ":", v-curpsn).
DO WHILE TRUE:
IF v-idxplus = 0 THEN DO:
IF v-idxcolon = 0 THEN LEAVE. /* no more delimiters */
/* Otherwise, next delim is a colon */
v-element = SUBSTRING(segment, v-curPsn, v-idxcolon - v-curPsn).
v-curpsn = v-idxcolon + 1.
/* No need to recalculate v-idxplus */
v-idxcolon = INDEX(segment, ":", v-curpsn).
END.
ELSE DO: /* v-idxplus > 0 */
IF v-idxcolon = 0 OR v-idxcolon > v-idxplus THEN DO:
/* Either no colons, or next delim is a plus */
v-element = SUBSTRING(segment, v-curPsn, v-idxplus - v-curPsn).
v-curpsn = v-idxplus + 1.
/* No need to recalculate v-idxcolon */
v-idxplus = INDEX(segment, "+", v-curpsn).
END.
ELSE DO: /* both > 0, but idxplus is next delim */
v-element = SUBSTRING(segment, v-curPsn, v-idxcolon - v-curPsn).
v-curpsn = v-idxcolon + 1.
/* No need to recalculate v-idxplus */
v-idxcolon = INDEX(segment, ":", v-curpsn).
END.
END.
/*
** Display result. Skip empty elements. If you want to ignore
** pure white space (e.g. " "), then you can change this to
** IF v-element <> ""
*/
IF LENGTH(v-element) > 0 THEN DO:
MESSAGE v-element
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END.
END.
/*
** No more delimiters. But there still might be one element left */
IF v-curpsn < LENGTH(segment) THEN DO:
v-element = SUBSTRING(segment, v-curPsn).
MESSAGE v-element
VIEW-AS ALERT-BOX INFO BUTTONS OK.
END.
END