如果您只有两个分隔符,则此代码是执行搜索的干净方式。它可以扩展到三个或更多的分隔符,但我可能会以不同的方式构造代码。 (我会遍历分隔符列表,让我知道你是否需要这样的代码。)
此代码的一个目的是最小化执行的字符串搜索次数。与每次查找后都搜索两个分隔符相比,它足够聪明,只需搜索一个。我相信这会使其性能不失明确 - 但我没有做基准测试,而且我可能是错的。一如既往,最佳解决方案将取决于数据的性质。
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