Scott Roth · Jul 8, 2019

How do you loop through a string, and split the string up based on the number of characters

Way back when during our Siemens LCR days we had to limit the number of characters in OBX.5 to a length of 75. That was back when we had eGate.

Now I need to do the reversal of that and take loop through a string length and split the string up into multiple OBX or NTE based on a certain length. In reading documentation $EXTRACT can do this if you know the exact length, but in this case we don't. 

So how would one loop through a string and say every 75 characters create a new OBX or NTE segment?



0 2,015
Discussion (6)5
Log in or sign up to continue

as a quick approach:

  set instring="........whatever you  need .........."
  set len=75
  for part=0:1 {
    set segment=$extract(instring,part*len+1,part+1*len)
    do OBX(segment)
  if $length(instring)<(part+1*len+1)  quit      ; nothing left

;;; have no details how OBX looks like but this are the pieces

/// pStr - Complete string that require to split
/// pByLen - Length you want in each part
/// arrObx - passed by reference to store each OBx in array

ClassMethod SplitByLen(pStr As %String, pByLen As %Integer, ByRef arrObx) As %Status
   Set (startPos,obxCntr)=0
      Quit:'(startPos < $L(pStr))
      Set arrObx($I(obxCntr)) = $E(pStr,$I(startPos),startPos+pByLen-1)
      Set startPos = startPos + pByLen
   Quit $$$OK

Scott, is there any requirement that this field be split along word boundaries such as whitespace and punctuation characters? That makes it a bit more challenging :)

The Mighty Jeffrey Drumm!

Yes there is a requirement to split on words.   Otherwise we would be simply using a similar loop as above on substring and dumping the output into OBX5's.

Chuck Kozak

OK, it's quick and dirty and I'm probably doing something that will make the old-timers here laugh hysterically, but it works. The caveats are:

  • It only cares about word wrapping on the space character. Punctuation adjacent to non-space characters will stay with the adjacent characters.
  • It totally ignores things like \.br\ tags. they're just text as far as it's concerned.
  • It returns a $LIST, where each list element is a line of text from the source string, no longer than the width specified. You can iterate through it with $LISTNEXT or $LISTGET and populate your OBX segments, but you'll probably have to do that in a CODE rule.

So anyway ...

ClassMethod WordWrap(pTxt As %String, pWidth As %Integer) As %List
    If $LENGTH(pTxt) > pWidth
        set tLine = ""
        Set tCnt = 0
        Set tWordList = $LFS(pTxt," ")
        Set tListLen  = $LISTLENGTH(tWordList)
        Set tWordPtr = 0
        Set tWordCur = ""
        While $LISTNEXT(tWordList,tWordPtr,tWordCur)
            If $LENGTH(tLine_tWordCur) > pWidth
                Set $LIST(tList,*+1) = $ZSTRIP(tLine,">W")
                Set tLine = tWordCur_" "
                Set tLastCnt = tCnt
                Set tLine = tLine_tWordCur_" "
            Set tCnt = tCnt + 1
 	Set tList = $LB(pTxt)
	Set (tLastCnt,tListLen) = 0
    If tLastCnt < tListLen
         Set $LIST(tList,*+1) = $LTS($LIST(tWordList,tLastCnt + 1,tListLen)," ")
    Return tList

Have fun!