简体   繁体   English

如何找到用隔行号分隔的字符串的索引openge 4gl?

[英]How to find the index of the string separated by delimeters in progress openedge 4gl?

I want to find the index of 56 in "STS++5623+56+ 123 " . 我想在“ STS ++ 5623 + 56 + 123”中找到索引56。 The code I have written gives me 6 (of 5623) but I need 11. 我编写的代码给了我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.

Sorry the previous answer wasn't what you needed. 抱歉,上一个答案不是您所需要的。 I decided to leave it up, because it is a nice solution to the problem as stated. 我决定将其保留,因为它可以很好地解决上述问题。 But I'll try again. 但我会再试一次。 I made the check for delimiters a separate function so you can easily adapt it to your requirements. 我将分隔符检查设为单独的功能,因此您可以轻松地将其适应您的要求。 Adding multi-byte character capabilities should be straightforward. 添加多字节字符功能应该很简单。

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

There are several ways to approach this. 有几种方法可以解决此问题。 Which is smartest depends upon the data. 哪一个最聪明取决于数据。 I can think of two that do not involve loops, which may be what you are looking for. 我可以想到两个不涉及循环的问题,这可能正是您要寻找的。 I haven't done any benchmarking, but I think the code below would is the most efficient algorithm. 我尚未进行任何基准测试,但我认为下面的代码将是最有效的算法。 At most it involves three string searches -- one entry() , one num-entries() , and one index() . 最多包含三个字符串搜索-一个entry() ,一个num-entries()和一个index() If this doesn't meet your needs, I can suggest alternatives. 如果这不能满足您的需求,我可以建议其他方法。

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM