我想在“STS ++ 5623 + 56 + 123”中找到56的索引。我写的代码给了我6(5623),但我需要11。
DEFINE var v-segment as longchar no-undo.
DEFINE VARIABLE v-element AS CHARACTER NO-UNDO.
ASSIGN v-segment = "STS++5623+56".
ASSIGN v-element = "56".
define variable v-index as integer no-undo.
v-index = index(v-segment , v-element , 1).
MESSAGE v-index
VIEW-AS ALERT-BOX INFO BUTTONS OK.
答案 0 :(得分:1)
很抱歉,之前的答案不是您所需要的。我决定放弃它,因为它是解决问题的一个很好的解决方案。但我会再试一次。我对分隔符的检查是一个单独的功能,因此您可以轻松地根据您的要求进行调整。添加多字节字符功能应该很简单。
DEFINE VARIABLE v-segment AS LONGCHAR NO-UNDO.
DEFINE VARIABLE v-element AS CHARACTER NO-UNDO.
DEFINE VARIABLE v-delims AS CHARACTER NO-UNDO.
DEFINE VARIABLE v-index AS INTEGER NO-UNDO.
DEFINE VARIABLE v-delimCount AS INTEGER NO-UNDO.
DEFINE VARIABLE v-segLength AS INTEGER NO-UNDO.
DEFINE VARIABLE v-eltLength AS INTEGER NO-UNDO.
DEFINE VARIABLE v-psn AS INTEGER NO-UNDO.
ASSIGN v-segment = "STS++5623+56"
v-element = "56"
v-delims = "+:"
/* For efficiency, don't calculate these inside your loop */
v-seglength = LENGTH( v-segment)
v-eltLength = LENGTH( v-element)
v-delimCount = LENGTH( v-delims).
/*
** isDelin()
** Is character at specified positiion one of the delimiters?
**
** Params:
** CHARACTER p-str - string to search
** INTEGER p-psn - position to check
** CHARACTER p-delims - list of delimiters to check for
**
** Returns TRUE if character at specified position is a delimiter
** Otherwise, returns FALSE
*/
FUNCTION isDelim RETURNS LOGICAL (
INPUT p-str AS LONGCHAR,
INPUT p-psn AS INTEGER,
INPUT p-delims AS CHARACTER
):
/* You might want parameter checking here.... */
RETURN INDEX( p-delims, SUBSTRING( p-str, p-psn, 1)) > 0.
END FUNCTION. /* isDelim */
/*
** You might want special case handling here:
** if v-eltLength = 0 then v-index = 1. return.
** IF v-element = ? or v-segment = ? then v-index = 0. return.
*/
/* Look for v-element, then see if it is surrounded by delimiters */
v-index = 0.
DO WHILE TRUE:
v-index = INDEX( v-segment, v-element, v-index + 1).
If v-index = 0 THEN LEAVE. /* No more matches */
/*
** Found a match. Is it preceded by a delimiter?
** (Don't check if match is at beginning of string.)
*/
v-psn = v-index - 1.
IF v-psn > 0 AND NOT isDelim( v-segment, v-psn, v-delims) THEN NEXT.
/*
** Is match followed by a delimiter?
** (Don't check if match is at end of string.)
*/
v-psn = v-index + v-eltLength.
IF v-psn > v-seglength THEN LEAVE.
IF NOT isDelim(v-segment, v-psn, v-delims) THEN NEXT.
/* Success! */
LEAVE.
END.
MESSAGE v-index VIEW-AS ALERT-BOX INFO BUTTONS OK.
答案 1 :(得分:0)
DEFINE var v-segment as longchar no-undo.
DEFINE VARIABLE v-element AS CHARACTER NO-UNDO.
def var v-i as int no-undo.
def var v-data as char no-undo.
ASSIGN v-segment = "STS++5623+56+123".
ASSIGN v-element = "56".
define variable v-index as integer no-undo.
do v-i = 1 to num-entries(v-segment,"+"):
if entry(v-i,v-segment,"+") = v-element then
do:
v-data = entry(v-i,v-segment,"+").
MESSAGE v-data VIEW-AS ALERT-BOX INFO BUTTONS OK.
end.
end.
答案 2 :(得分:0)
有几种方法可以解决这个问题。哪个最聪明取决于数据。我可以想到两个不涉及循环,这可能是你正在寻找的。我还没有完成任何基准测试,但我认为下面的代码是最有效的算法。最多涉及三个字符串搜索 - 一个entry()
,一个num-entries()
和一个index()
。如果这不能满足您的需求,我可以提出替代方案。
DEFINE VARIABLE v-segment AS LONGCHAR NO-UNDO.
DEFINE VARIABLE v-element AS CHARACTER NO-UNDO.
DEFINE VARIABLE v-index AS INTEGER NO-UNDO.
DEFINE VARIABLE v-entry AS INTEGER NO-UNDO.
DEFINE VARIABLE v-delim AS CHARACTER NO-UNDO.
ASSIGN v-segment = "STS++5623+56"
v-element = "56"
v-delim = "+".
/* Does the segment contain the exact entry? */
v-entry = LOOKUP(v-element, v-segment, v-delim).
/*
** If entry number = 0, then element is not found
** If entry number = 1, then element is at beginning of segment.
** If entry number = num-entries(), then element is at end of segment
** Otherwise, element is in the middle; just search for it surrounded
** by delimters.
*/
IF v-entry = 0 THEN
v-index = 0.
ELSE IF v-entry = 1 THEN
v-index = 1.
ELSE IF v-entry = NUM-ENTRIES( v-segment, v-delim) THEN
v-index = R-INDEX( v-segment, v-delim) + 1.
else
v-index = INDEX( v-segment, v-delim + v-element + v-delim) + 1.
MESSAGE v-index VIEW-AS ALERT-BOX INFO BUTTONS OK.