Difference between revisions of "LlSubStringIndex"

From Second Life Wiki
Jump to navigation Jump to search
m
Line 42: Line 42:
} else {
} else {
     llSay(0,"TEST was found in the string.");
     llSay(0,"TEST was found in the string.");
}</lsl>
=== String Cheese ===
<lsl>string string_example = "ThIs serVes As aN exaMplE sTrinG. It ISn't toO coMPleX bUt HaS sOme mIlD vARietY";
string search_test_a = "search FOR";//Finish this statement with the word (or group of words) you wish to search "string_example" for.
                                    //You may say it in any case (upper or lower).
                                   
string search_test_b = "is the word I seek";//Begin this statement with the word (or group of words) you seek in "string_example".
                                            //This way will require you to search for a literal (case sensitive) match. Good luck.
string search_word;
default
{
    on_rez(integer param)
    {
        llResetScript();
    }
    state_entry()
    {
        llSetObjectName("String Cheese");
        llListen(0, "", llGetOwner(), "");
    }
    listen(integer chan, string name, key id, string msg)
    {
        if(llSubStringIndex(llToUpper(msg), llToUpper(search_test_a)) != -1)
          //Since searches are case sensitive avoid trouble by using llToUpper or llToLower
        {
            search_word = llStringTrim(llGetSubString(msg, llStringLength(search_test_a), -1), STRING_TRIM);
            //Store the search word as it was typed and trim off any excess
            if(llSubStringIndex(llToUpper(string_example), llToUpper(search_word)) != -1)//Convert for less sensitive searching
            {
                llSay(0, "I have found the word " + "''" + search_word + "''" + " in the example string");
            }
            else                        //Send back in same case as was typed
            {
                llSay(0, "I cannot find the word " + "''" + search_word + "''" + " in the example string.");
            }
        }
        if(llSubStringIndex(msg, search_test_b) != -1)//A perfect match is required
        {
            search_word = llStringTrim(llGetSubString(msg, 0, (llSubStringIndex(msg, search_test_b)-1)), STRING_TRIM);
            if(llSubStringIndex(string_example, search_word) != -1)
            {
                llSay(0, "I have found the word " + "''" + search_word + "''" + " in the example string");
                //You would be quite lucky or patient to get a match here
            }
            else
            {
                llSay(0, "I cannot find the word " + "''" + search_word + "''" + " in the example string.");
            }
        }
    }//Used with lists this is a powerful and very useful function. Grabbing an integer can allow you to dig through info in many ways.
}</lsl>
}</lsl>
|helpers=
|helpers=

Revision as of 19:13, 16 June 2009

Summary

Function: integer llSubStringIndex( string source, string pattern );
0.0 Forced Delay
10.0 Energy

Returns an integer that is the index of pattern in source.

• string source
• string pattern

If pattern is not found in source, -1 is returned.
The index of the first character in the string is 0

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.
  • There is no function to search the string from the end or search starting at a specific offset.

Examples

Matching against last names: <lsl> default {

   state_entry()
   {
       llSensorRepeat("", NULL_KEY, AGENT, PI, 96.0, 20);
   }
   
   sensor(integer NumDet)
   {
       integer i;
       
       //Loop through all the sensor data and match against " Linden", 
       //this causes it to match with any last name of Linden (since there can't be spaces before the firstname)
       //Alternatively you could match a firstname with "FirstName "
       for(i = 0; i < NumDet; ++i)
           if(~llSubStringIndex(llDetectedName(i), " Linden"))
               llInstantMessage(llDetectedKey(i), "Hello, I see you!");
   }

} </lsl>

Basic Example: <lsl>integer index = llSubStringIndex("string data","TEST"); if(index == -1) {

   llSay(0,"TEST was not found in the string");

} else {

   llSay(0,"TEST was found in the string.");

}</lsl>

String Cheese

<lsl>string string_example = "ThIs serVes As aN exaMplE sTrinG. It ISn't toO coMPleX bUt HaS sOme mIlD vARietY";

string search_test_a = "search FOR";//Finish this statement with the word (or group of words) you wish to search "string_example" for.

                                   //You may say it in any case (upper or lower).
                                   

string search_test_b = "is the word I seek";//Begin this statement with the word (or group of words) you seek in "string_example".

                                           //This way will require you to search for a literal (case sensitive) match. Good luck.

string search_word;

default {

   on_rez(integer param)
   {
       llResetScript();
   }
   state_entry()
   {
       llSetObjectName("String Cheese");
       llListen(0, "", llGetOwner(), "");
   }
   listen(integer chan, string name, key id, string msg)
   {
       if(llSubStringIndex(llToUpper(msg), llToUpper(search_test_a)) != -1)
          //Since searches are case sensitive avoid trouble by using llToUpper or llToLower
       {
           search_word = llStringTrim(llGetSubString(msg, llStringLength(search_test_a), -1), STRING_TRIM);
           //Store the search word as it was typed and trim off any excess
           if(llSubStringIndex(llToUpper(string_example), llToUpper(search_word)) != -1)//Convert for less sensitive searching
           {
               llSay(0, "I have found the word " + "" + search_word + "" + " in the example string");
           }
           else                         //Send back in same case as was typed
           {
               llSay(0, "I cannot find the word " + "" + search_word + "" + " in the example string.");
           }
       }
       if(llSubStringIndex(msg, search_test_b) != -1)//A perfect match is required
       {
           search_word = llStringTrim(llGetSubString(msg, 0, (llSubStringIndex(msg, search_test_b)-1)), STRING_TRIM);
           if(llSubStringIndex(string_example, search_word) != -1)
           {
               llSay(0, "I have found the word " + "" + search_word + "" + " in the example string");
               //You would be quite lucky or patient to get a match here
           }
           else
           {
               llSay(0, "I cannot find the word " + "" + search_word + "" + " in the example string.");
           }
       }
   }//Used with lists this is a powerful and very useful function. Grabbing an integer can allow you to dig through info in many ways.
}</lsl>

Useful Snippets

Tests to see if one string contains a copy of another:

1. Concise & conventional:

<lsl> integer contains(string haystack, string needle) // http://wiki.secondlife.com/wiki/llSubStringIndex {

   return 0 <= llSubStringIndex(haystack, needle);

} </lsl>

<lsl>integer startswith(string haystack, string needle) // http://wiki.secondlife.com/wiki/llSubStringIndex {

   return llDeleteSubString(haystack, llStringLength(needle), -1) == needle;

}</lsl>

<lsl>integer endswith(string haystack, string needle) // http://wiki.secondlife.com/wiki/llSubStringIndex {

   return llDeleteSubString(haystack, 0, ~llStringLength(needle)) == needle;

}</lsl>

Note: Some of the snippets above return a result without ever calling llSubStringIndex.

2. Clever & smaller (calculates contains in ~54 bytes rather than ~60):

<lsl>integer contains(string haystack, string needle) // http://wiki.secondlife.com/wiki/llSubStringIndex {

   return ~llSubStringIndex(haystack, needle);

}</lsl>

Note: The llSubStringIndex function returns -1 only when not found and the ~ operator returns zero only for -1, so the clever combination ~llSubStringIndex returns zero only for not found, else nonzero for found.

Note: Smaller was not noticeably faster or slower when our Code Racer and Efficiency Tester harnesses measured the expression { contains("wiki.secondlife.com", "wiki"); }.

See Also

Functions

•  llListFindList Find a list in another list
•  llGetSubString Copy out part of a string of characters

Deep Notes

Signature

function integer llSubStringIndex( string source, string pattern );