如何查找正在进行的分隔符分隔的字符串的索引openge 4gl?

时间:2016-03-25 07:28:12

标签: string indexing progress-4gl openedge

我想在“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.

3 个答案:

答案 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.