如何在一次迭代中一次解析两个字符?

How to parse two characters at a time for one Iteration?

我有一个匹配 2 个字符并解析数据的书面查询,但我觉得我做的方式是错误的。让我和你分享我的逻辑

DEFINE VARIABLE I                   AS INTEGER   NO-UNDO.
DEFINE VARIABLE cData               AS CHARACTER NO-UNDO.
DEFINE VARIABLE cParsData           AS CHARACTER NO-UNDO.

ASSIGN
       cData = 'PRRSCLPP0123456789'.

DO I = 1 TO LENGTH(cData):

   cParsData = SUBSTRING(cData,I).
   IF cParsData MATCHES 'PP*' THEN MESSAGE SUBSTRING(cParsData,4,9).

END.

如您所见,我的做法是错误的,我认为它每次迭代都会解析每个字符,但我需要的是每次迭代应该解析两个字符,以便我们可以匹配 "PP"。您可以共享或更改不同方式的逻辑以获得相同的输出

不太明白你想做什么。您要搜索字符串并查看其中是否有 "PP" 吗?然后你不需要在迭代中做它。简直

cData MATCHES "*PP*" 会告诉你的。

如果 "PP" 是某种分隔符,并且您想对前后的数据做一些事情,您可以这样做:

DEFINE VARIABLE I                   AS INTEGER   NO-UNDO.
DEFINE VARIABLE cData               AS CHARACTER NO-UNDO .
DEFINE VARIABLE cParsData           AS CHARACTER NO-UNDO.

ASSIGN
   cData = 'PRRSCLPP0123456789'.

DO I = 1 TO LENGTH(cData):

    cParsData = SUBSTRING(cData,I, 2).
    IF cParsData = 'PP' THEN DO:
        DISPLAY 
            SUBSTRING(cData, i + 2)    FORMAT "x(20)" LABEL "After PP" 
            SUBSTRING(cData, 1, i - 1) FORMAT "x(20)" LABEL "Before PP".
    END.

END.

不过,这仅适用于字符串中 "PP" 的一次出现。你应该试着更好地解释你到底在追求什么。

您在另一个答案的评论中留下了更多信息:

如果 PP 确实总是在位置 10(和 11)或 20(和 21)并且您只想要以下 10 个字符,那么您可以这样做:

DEFINE VARIABLE cData1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE cData2 AS CHARACTER NO-UNDO.
/* Position 10 and 11 */
cData1 = 'PRRSCLAAAPP0123456789'.
/* Position 20 and 21 */
cData2 = 'PRRSCLAAAPRRSCLAAAPP9876543210AA'.

FUNCTION parse  RETURNS CHARACTER 
    (INPUT cString AS CHARACTER ):
    IF INDEX(cString, "PP") > 0 THEN 
        RETURN SUBSTRING(cString, INDEX(cString, "PP") + 2, 10 ).
    ELSE 
        RETURN "".

END.

 MESSAGE cData1 " ->" parse(cData1) SKIP
         cData2 " ->" parse(cData2) VIEW-AS ALERT-BOX.

很难想象一次遍历字符串一个字符以查找 "PP" 然后吐出字符 4 到 13 的原因。这样做会简单得多:

define variable myData  as character no-undo.
define variable foundIt as integer   no-undo.

myData = "PRRSCLPP0123456789".

foundIt = index( myData, "PP" ).
if foundIt > 0 then 
  message substring( myData, 4, 9 ).

如果有理由一次通过该字符串一个字符,我认为它不能包含在您的代码示例或问题中。

附带说明:MATCHES "PP*" 等同于 BEGINS "PP"。在这种情况下无关紧要,但在字符串比较时不必要地抛出 MATCHES 是一个坏习惯。特别是如果该习惯以 WHERE 子句结束。在 WHERE 子句中使用 MATCHES 将导致 table 扫描。这几乎总是一个坏主意。

如果你试图在找到 "PP" 的位置之后输出 N 个字符(而不是 hard-coded 4 到 13)你会这样做(假设 n = 9) :

define variable myData  as character no-undo.
define variable foundIt as integer   no-undo.

myData = "PRRSCLPP0123456789".

foundIt = index( myData, "PP" ).
if foundIt > 0 then 
  message substring( myData, foundIt + 1, 9 ).