如何在一次迭代中一次解析两个字符?
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 ).
我有一个匹配 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 ).