Difference between revisions of "SubStringLastIndex"

From Second Life Wiki
Jump to navigation Jump to search
m (More obvious this way (avoids the negative index issue), since we evaluate from right to left, the recursion should happen before the parameters for the add are pushed onto the stack.)
(Added fourth solution that uses the recent llReplaceSubString() function and NAK constant.)
 
(2 intermediate revisions by 2 users not shown)
Line 15: Line 15:
* MONO: 1024 bytes
* MONO: 1024 bytes
<!-- please replace with a similarly licensed version only -->
<!-- please replace with a similarly licensed version only -->
<lsl>integer uSubStringLastIndex( string vStrSrc, string vStrTst ){
<source lang="lsl2">integer uSubStringLastIndex( string vStrSrc, string vStrTst ){
     integer vIdxFnd =
     integer vIdxFnd =
       llStringLength( vStrSrc ) -
       llStringLength( vStrSrc ) -
Line 30: Line 30:
/*//  2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ]  //*/
/*//  2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ]  //*/
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//--                                                                --//*/</lsl>
/*//--                                                                --//*/</source>




'''Code:'''
'''Code:'''
Alternative implementation - may be faster, but untested.
Alternative implementation - may be faster, tested.


''(warning: uses recursion, high potential for LSL stack heap collision when processing large and/or highly repetitive strings)''
''(warning: uses recursion, high potential for LSL stack heap collision when processing large and/or highly repetitive strings)''
<lsl>integer uSubStringLastIndex(string vStrSrc, string vStrTst)
<source lang="lsl2">integer uSubStringLastIndex(string vStrSrc, string vStrTst)
{
{
     if (vStrTst == "")
     if (vStrTst == "")
         return 0;
         return 0;
     integer index = llSubStringIndex(vStrSrc, vStrTst);
     integer index = llSubStringIndex(vStrSrc, vStrTst);
     if (index == -1) //found, look again
    integer index2;
         return -1;
     if (index != -1) //found, look again
    return index + 1 + uSubStringLastIndex(llDeleteSubString(vStrSrc, 0, index), (vStrSrc = vStrTst = "") + vStrTst);
         index2 = uSubStringLastIndex(llGetSubString(vStrSrc, index + 1, -1), vStrTst) + 1;
    return index + index2;
}
}
/*// Contributed Freely to the Public Domain without limitation by Sasun Steinbeck. //*/</lsl>
/*// Contributed Freely to the Public Domain without limitation by Sasun Steinbeck. //*/</source>
 
Third solution, tested
<source lang="lsl2">
integer uSubStringLastIndex(string hay, string pin)
{
    integer index2 = -1;
    integer index;
    if (pin == "")   
        return 0;
    while (~index)
    {
        index = llSubStringIndex( llGetSubString(hay, ++index2, -1), pin);
        index2 += index;
    }
    return index2;
}
</source>
 
Fourth solution, tested
<source lang="lsl2">
integer uSubStringLastIndex(string haystack, string needle)
{
    return llSubStringIndex(llReplaceSubString(haystack, needle, NAK, -1), NAK); //make sure the value for NAK won't ever natively/naturally occur in source string, else, use a different unique string for pattern
}
/*// Contributed Freely to the Public Domain without limitation by Lucia Nightfire. //*/
</source>
}}
}}



Latest revision as of 18:07, 21 February 2024

User-Defined Function: integer uSubStringLastIndex( string vStrSrc, string vStrTst );

Returns a integer that is the positive index of the last vStrTst within vStrSrc

  • vStrSrc: source string to check
  • vStrTst: string to look for

if vStrTst is not found in vStrSrc -1 is returned.
the index of the first character is 0


Code:

  • LSO: 182 bytes
  • MONO: 1024 bytes
integer uSubStringLastIndex( string vStrSrc, string vStrTst ){
    integer vIdxFnd =
      llStringLength( vStrSrc ) -
      llStringLength( vStrTst ) -
      llStringLength(
        llList2String(
          llParseStringKeepNulls( vStrSrc, (list)vStrTst, [] ),
          0xFFFFFFFF ) //-- (-1)
        );
    return (vIdxFnd | (vIdxFnd >> 31));
}
/*//--                       Anti-License Text                         --//*/
/*//     Contributed Freely to the Public Domain without limitation.     //*/
/*//   2009 (CC0) [ http://creativecommons.org/publicdomain/zero/1.0 ]   //*/
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
/*//--                                                                 --//*/


Code: Alternative implementation - may be faster, tested.

(warning: uses recursion, high potential for LSL stack heap collision when processing large and/or highly repetitive strings)

integer uSubStringLastIndex(string vStrSrc, string vStrTst)
{
    if (vStrTst == "")
        return 0;
    integer index = llSubStringIndex(vStrSrc, vStrTst);
    integer index2;
    if (index != -1) //found, look again
        index2 = uSubStringLastIndex(llGetSubString(vStrSrc, index + 1, -1), vStrTst) + 1;
    return index + index2;
}
/*// Contributed Freely to the Public Domain without limitation by Sasun Steinbeck. //*/

Third solution, tested

integer uSubStringLastIndex(string hay, string pin)
{
    integer index2 = -1;
    integer index;
    if (pin == "")    
        return 0;
    while (~index)
    {
        index = llSubStringIndex( llGetSubString(hay, ++index2, -1), pin);
        index2 += index;
    }
    return index2;
}

Fourth solution, tested

integer uSubStringLastIndex(string haystack, string needle)
{
    return llSubStringIndex(llReplaceSubString(haystack, needle, NAK, -1), NAK); //make sure the value for NAK won't ever natively/naturally occur in source string, else, use a different unique string for pattern
}
/*// Contributed Freely to the Public Domain without limitation by Lucia Nightfire. //*/

Caveats

  • Performs a literal match (case sensitive).
    • Wildcards and RegEx are not supported.
  • Attempting to match an empty string ("") will return 0 instead of -1.

Notes

  • This function is operates exactly like llSubStringIndex (including caveats), from the opposite end of the string.