Separate Words

From Second Life Wiki
Revision as of 07:28, 8 September 2007 by Ppaatt Lynagh (talk | contribs) (work around the llParseString2List limit of 8 spacers or separators)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Separate Words

LSL defines llParseString2List to divide a source string into words. That function sees the chars between separators or spacers, and each spacer, as a word (except that function never sees the empty string as a word).

Trouble is, LSL doesn't let you choose more than 8 spacers or separators, if you call llParseString2List directly.

You can substitute a call to the separateWords function here in place of your call to llParseString2List whenever you have more than 8 separators or more than 8 spacers.

The code follows:

// Call llParseString2List for each of the sources.
// Return the results in order.
// cf. http://wiki.secondlife.com/wiki/Separate_Words

list applyLlParseString2List(list sources, list separators, list spacers)
{
    list words = [];
    integer index;
    integer lenSources = llGetListLength(sources);
    for (index = 0; index < lenSources; ++index)
    {
        string source = llList2String(sources, index);
        words += llParseString2List(source, separators, spacers);
    }
    return words;
}

// Divide a source string into words.
// See the chars between separators or spacers, and each spacer, as a word.
// Never see the empty string as a word.
// cf. http://wiki.secondlife.com/wiki/Separate_Words

list separateWords(string chars, list separators, list spacers)
{
    
    // Begin with all chars in one word
    
    list words = [chars];
    
    // List the chars between spacers, and each spacer, as a word
     
    integer index;
    integer lenSpacers = llGetListLength(spacers);
    for (index = 0; index < lenSpacers; index += 8)
    {
        list some = llList2List(spacers, index, index + 8 - 1);
        words = applyLlParseString2List(words, [], some);
    }        
    
    // Discard the separators after letting the separators separate words
     
//  integer index;
    integer lenSeparators = llGetListLength(separators);
    for (index = 0; index < lenSeparators; index += 8)
    {
        list some = llList2List(separators, index, index + 8 - 1);
        words = applyLlParseString2List(words, some, []);
    }
    
    // Succeed
        
    return words;
}

// Demo

string lf = "\n";
string quote = "\"";
string escape = "\\";

list spacers = [quote, "(", ")", "<", ">", "[", "]", "/", "+", "-", "*", "%", escape];

list separators()
{
    string tab = llUnescapeURL("%09"); // != "\t"
    string cr = llUnescapeURL("%0D"); // != "\r"
    return [tab, lf, cr, " ", ",", ";"];
}

default
{
    state_entry()
    {
        
        string chars = "42 0.99 \"00000000-0000-0000-0000-000000000000\" [abc, def] \"xyz\\\\\"zyx\" <0, 1, 2, 3> // source literals";
        list words = separateWords(chars, separators(), spacers);

        integer index;
        integer lenWords = llGetListLength(words);
        for (index = 0; index < lenWords; ++index)
        {
            llOwnerSay((string) index + ": " + llList2String(words, index));
        }
        
        llOwnerSay("OK");
    }
}