StringTheory Replace strangeness with < 0dh,0ah >

I am a bit confused as to why the StringTheory code below doesn’t work calling ST.Replace

original string is

Bank <0DH,0aH> Payment 1
St                   StringTheory                         
tmp:str              CSTRING(5001)                

  CODE

    dbgView('CleanUpCRLF original: ' & tmp:str)

    st.SetValue(tmp:str)
    st.Replace('<0dh,0ah>','',,,,1) ! CR/LF  case-insensitive
    
    st.Replace('bank','PranK',,,,1) ! test, works
    
    tmp:str = st.GetValue()
    
    dbgView('CleanUpCRLF cleaned:  ' & tmp:str)

so I passed the string and got this debug output:

CleanUpCRLF original: Bank <0DH,0aH> Payment 1
CleanUpCRLF cleaned:  PranK <0DH,0aH> Payment 1

what is wrong with a code?? Bank has been replaced, but <0DH,0aH> not.

I expect what’s in the string to begin with is not what you think is in the string to begin with.
In Clarion the Single < has specific meaning when used in a String that converts to Binary ASCII codes.
So
st.Replace('<0dh,0ah>')
Means the same as
st.Replace( chr(0Dh) & chr(0Ah) )

But I’m not sure that your original text contains chr(13) chr(10). I think it contains the characters: <0Dh> etc. As evidenced by you seeing that string in the Debugview output.
(it’s weird to see text like that in a string, but hey, it’s your string.)
You might have more success with;
st.Replace('<<0dh,0ah>')
That forces the first parameter there to be “plain text”.

2 Likes

Thanks, Bruce

this works
st.Replace('<<0dh,0ah>','',,,,1) ! CR/LF case-insensitive

note double <<

CleanUpCRLF original Bank <0DH,0aH> Payment 1
CleanUpCRLF cleaned  PranK  Payment 1

I have some String Theory Tools on GitHub you may find helpful when writing ST code to insure your code is doing exactly what you want.

There’s Scratch Theory for writing this kind of test code in a hand code project. In that is handy to use Big Bang Theory that let’s you see in a Window what’s inside ST (including seeing it in Hex) to confirm its what you think it is. It’s small with 9 calls like Bang.ValueView(ST).

Write Theory makes it easier to code the ST calls that have so many parameters (too many) like getting True for the 6th parameter for No Case in Replace. This works by reading the INC file so adapts as the class changes.

2 Likes

FYI because you write templates as well iirc.

You have to use the same in template code as well ie using << instead of < because of the dot net ide.

There was a problem I faced where the template code converted it when the c11 ide crashed (I’ve got some interesting bugs to report when I get a chance) so the work around for the templates was to create a template variable called %crlf and then assign the <<0dh,0ah> to %crlf early on in the template chain then the templates don’t interpret it wrong when a template writes a template.

Edit.

Here’s a template group which removes the 0dh,0ah aka 13,10 aka cr,lf from template input text fields using regex.


 #Group( %ISTB3valValidateRemoveCarriageReturnLineFeeds, *%pText, Long %pAddSpaceCharacters = 0 ), Auto
#! App File : TB4_22.APP
   #Declare( %StringLength, Long )
   #Declare( %StringSearch, String )
   #Declare( %StringMatchBefore, String )
   #Declare( %StringMatchAfter, String )
   #Declare( %RegEx, String )
   #Declare( %StrPosResult, Long )
   #Set( %StringSearch,  %pText )
   #Set( %RegEx,  '{{<0DH,0AH>}' )                             #! 13,10 in hex and treat as two characters in all calculations not as one control code.
   #Set( %StringLength,  Len(%StringSearch) )
   #!Error( '%StringSearch = ' & %StringSearch )
   #Loop
   #Set( %StrPosResult,  StrPos(%StringSearch, %RegEx, 1) )
   #Case( %StrPosResult )
   #OF( 0 )
   #!Error( 'OF 0 %StrPosResult = ' & %StrPosResult &' %StringLength = ' & %StringLength )
   #Break
   #OF( 1 )
   #!Error( 'OF 1 %StrPosResult = ' & %StrPosResult &' %StringLength = ' & %StringLength )
   #Set( %StringMatchBefore,  '' )
   #Set( %StringMatchAfter,  Sub( %StringSearch, %StrPosResult + 2, %StringLength - ( %StrPosResult + 1 ) ) )
   #Set( %StringSearch,  %StringMatchAfter )
   #OF( %StringLength - 1 )                                    #! The RegEx is treated as two characters hence the -1 to reduce the String Length
   #!Error( 'OF %StringLength %StrPosResult = ' & %StrPosResult &' %StringLength = ' & %StringLength )
   #Set( %StringMatchBefore,  Sub( %StringSearch, 1, %StrPosResult - 1 ) )
   #Set( %StringMatchAfter,  '' )
   #Set( %StringSearch,  %StringMatchBefore )
   #Else
   #!Error( 'OF Else %StrPosResult = ' & %StrPosResult &' %StringLength = ' & %StringLength )
   #Set( %StringMatchBefore,  Sub( %StringSearch, 1, %StrPosResult - 1 ) )
   #Set( %StringMatchAfter,  Sub( %StringSearch, %StrPosResult + 2, %StringLength - (%StrPosResult + 1) ) )
   #Set( %StringSearch,  %StringMatchBefore )
   #Loop, Times( %pAddSpaceCharacters )
   #Set( %StringSearch,  %StringSearch & ' ' )
   #EndLoop
   #Set( %StringSearch,  %StringSearch & %StringMatchAfter )
   #EndCase
   #Set( %StringLength,  Len( %StringSearch ) )
   #!Error( 'Before EndLoop %StringLength = ' & %StringLength )
   #EndLoop
   #Set( %pText,  %StringSearch )
   #Return %True