I am trying to write a script step: Position( "TestTESTtest" , "test" , 1 , 1 )
And looking for 9 instead of 1.
I just wanted to suggest an alternative approach for your Script.
The ‘Exact’ function compares two values and is case-sensitive.
By combining the original ‘Position' function with ‘Exact’, you can get the result you are looking for.
The script loops through each successful ‘Position' result, exiting the loop when the result is an exact match.
Sorry, but I can’t get it down to one line!
Here is my solution;
Set Variable [ $Text; Value: "TestTESTtest" ]
Set Variable [ $SearchString; Value: "test” ]
Set Variable $Count; Value:1
Set Variable $Pointer; Value:Position ( $Text ; $SearchString ; 1 ; $Count )
Exit Loop If
Set Variable $Count; Value:$Count + 1
Show Custom Dialog [ Title: "Find Test"; Message: "Result: " & $Pointer ; Default Button: “OK”, Commit: “No” ]
Best wishes - Alan Stirling, London UK.
While you could use
Position( "TestTESTtest" , "test" , 1 , 3 )
to give you the result of 9, that certainly won't help for the general case.
The primary problem is that Position() is not case-sensitive.
There are other text functions that are case-sensitive. Substitute() is one of them.
You can use both Position and Substitute to achieve your desired result using something like the following.
sourceStr = "TestTESTtest";
searchStr = "test";
marker = "**unique_marker**"
Position(Substitute(sourceStr; searchStr; marker); marker;1; 1)
Pick the value for the marker variable such that it is something not found in the original sourceStr.
Alan: oops that didn't work. Must have pasted the wrong thing...
The email I received back from my post was not mangled, but the actual posting on the forum was indecipherable!
I've attached my test file.
Best wishes - Alan Stirling - London UK.
Thank you Alan,
I used the Exact function in a loop to solve the problem.
would use a little text algebra:
_text = Code ( "TestTESTtest" );
_search = Code ("test" ) ;
_pos = Position ( _text ; _search ; 1 ; 1 ) ;
_lng = Length ( _search ) ;
_cut = Middle ( _text ; _pos + _lng ; 999999 )
If ( _pos ; Length ( _cut ) / 5 + 1 ; 0 )
I can follow the steps easily enough but why does that work? Would you explain the logic for dummies like me?
Hello and Thank You to all,
This is how I solved the problem.
I have a text field that has "a" and "A" in it. I do not know the order, but I need to differentiate between the proper upper / lower case character and identify the position.
Since I know that there will only be one duplicate, it was somewhat simpler.
# g_num1 = character position
# g_string1 = my string = "aA"
# g_string2 = character I am looking for "A"
Set Field g_num1 = Position( g_string1 , g_string2 , 1 , 1 )
If( Exact( Middle( g_string1 , g_num2 , 1 ) , g_string2 )
# If first selected character is the exact upper / lower case match - we are done
# The first selected character is not the exact upper / lower case match, select the next one
Set Field g_num1 = Position( g_string1 , g_string2 , 1 , 2 )
Now I have the position of the exact upper / lower case match.
I got it except this:
What's the /5 + 1 have to do with it? or are you using the 4 character "code" as a way to grab what you want?
i think this might be invariant of character set ..
in case chars in argument used outside of 5 digits and easier to understand:
( _cut is the prefix which became the postfix after applying code function)
_cut = Middle ( _text ; _pos + _lng ; 999999 )
If ( _pos ; length ( char ( _cut )) + 1 ; 0 )
I think your solution is extremely clever.
If this technique were to be generalized, and the "spec" were that we are to identify the earliest match in the supplied text string, then I would propose the following variation of your calc:
_text = Code ( "TestTESTtestFootest" );
_search = Code ( "test" );
_len_text = Length( _text );
_lng_search = Length ( _search ) ;
_pos = Position ( _text ; _search ; _len_text; -1 ) ;
_cut = Middle ( _text ; _pos + _lng_search ; 999999 )
If ( _pos ; Length ( Char ( _cut ) ) + 1 ; 0 )
I realize that the OP did not specify to identify the earliest match, so, arguably, the above variation is no more or less valid as an answer to this post, but I make the note in case someone wants to generalize the technique, and they are expecting earliest match behavior.
Great thinking, and thanks for sharing! I think you made a few of us scratch our heads in order to follow along.
The use of the code function is very clever but note that it can only handle strings of 80 characters or less.
Try this, then change the 80 to 81:
Let( s = "0123456789012345678901234567890123456789"; Code( Left( S & S & "XXXX"; 80) ))
bruce, thanx for pointing this out. i would create then custom function
myCode with limit of 50k*80 chars
steve brilliant enhancements. now with bruce's pointed out limitation it almost calls for creating
a custom function PositionCaseSensitive ( .... )
This seems to work:
Position ( Substitute ( text ; text_to_locate ; "xxx" ) ; "xxx" ; 1 ; 1 )
I now see TomHays already suggested this, above !
Why was Alan's answer preferred over Tom's ? Tom's is the more elegant solution
> I am trying to write a script step: Position( "TestTESTtest" , "test" , 1 , 1 )
Retrieving data ...