Recipe#2.2: String Sets | Heaton Research

Recipe#2.2: String Sets

    Often it is desirable to test whether a string is in a specific set of characters. Recipe 2.2 allows a string to be tested to see whether the string is a member of one of the following sets:

  • Numeric
  • Alphabetic
  • Alphanumeric

    Recipe 2.2 is shown in Listing 2.2.

Listing 2.2: String Comparison (StringCompare.lsl)

// From the book:
//
// Scripting Recipes for Second Life
// by Jeff Heaton (Encog Dod in SL)
// ISBN: 160439000X
// Copyright 2007 by Heaton Research, Inc.
//
// This script may be freely copied and modified so long as this header
// remains unmodified.
//
// For more information about this book visit the following web site:
//
// http://www.heatonresearch.com/articles/series/22/

string CHARS = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~";


integer compareLen(string a, string b,integer len)
{
    integer result = 0;
    if(a != b)
    {
        integer index = 0;
        do
        {
            string chara = llGetSubString(a,index,index);
            string charb = llGetSubString(b,index,index);
             
            integer posa = llSubStringIndex(CHARS ,chara);
            integer posb = llSubStringIndex(CHARS ,charb);
             
            if((posa >= 0) && (posb >= 0))
            {
                result = posa - posb;
            }
            else if(posa >= 0)
            {
                result = 1;
            }
            else if(posb >= 0)
            {
                result = -1;
            }
             
            if(result != 0) index = len;
            ++index;
                 
        }
        while(index < len);
    }
         
    return result;
}

integer compareNoCaseLen(string a, string b,integer len)
{
    string stra = llToLower(a);
    string strb = llToLower(b);
    return compareLen(stra,strb,len);
}

integer compare(string a, string b)
{
    integer lena = llStringLength(a);
    integer lenb = llStringLength(b);
    integer result;
    if(lena < lenb)
        result =  compareLen(a,b,lena);
    else
        result =  compareLen(a,b,lenb);
     
    return result;
}


integer compareNoCase(string a, string b)
{
    integer la = llStringLength(a);
    integer lb = llStringLength(b);
    string stra = llToLower(a);
    string strb = llToLower(b);
    integer result;
    if(la < lb)
        result =  compareNoCaseLen(stra,strb,la);
    else
        result =  compareNoCaseLen(stra,strb,lb);
     
    return result;
}

// Some test uses
default
{
    state_entry()
    {
        llSay(0, "compareNoCase(hello,HELLO): " + (string)compareNoCase("jeff","Jeff") );   
        llSay(0, "compare(hello,HELLO): " + (string)compare("jeff","Jeff") );   
        llSay(0, "compare(aaa,bbb): " + (string)compare("aaa","bbb") );   
        llSay(0, "compare(aaa,bbb): " + (string)compare("bbb","aaa") ); 
    }
} 

    This recipe begins by defining several different character sets. The variable named CHARS holds all of the characters that this recipe deals with. The variable LETTERS holds the upper and lower case letters. The variable NUMBERS holds the ten digits.

string CHARS = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
string LETTERS= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string NUMBERS = "0123456789";

    These character sets will be used by the functions in this recipe.

Understanding the onlyContains Function

    The onlyContains function determines whether one string only contains characters from a second string. All of the other set functions are based upon the onlyContains function.

integer onlyContains(string a, string b)
{

    The onlyContains function accepts two parameters. The first parameter, a, specifies the string that is to be examined. The second parameter, b, is the set of characters that a should contain. If the a string only contains the characters in b, then the value of TRUE is returned, otherwise FALSE is returned.

    The function begins by obtaining the length of string a.

    integer l = llStringLength(a);
    integer result = FALSE;
    if(l != 0)
    {

    If string a has a zero length value, return FALSE, because string a contains no characters, let alone those specified in string b.

        result = TRUE;
        integer index = 0;
        do
        {

    The characters from string a are separated one by one and checked against string b.

            string chara = llGetSubString(a,index,index);
            integer posa = llSubStringIndex(b,chara);

    If the character is not found in string b, return FALSE.

            if(posa < 0)
            {
                result = FALSE;
                index = l;
            }
            ++index;

    Continue looping until the end of string a is reached.

        }
        while(index < l);
    }
    return result;
}

    Finally, return the result. Using the containsOnly function, a variety of useful set membership functions can be created. These will be discussed in the next sections.

Understanding the isNumeric Function

    The isNumeric function uses the onlyContains function to determine whether the specified string only contains digits. To do this, the NUMBERS variable, which contains the digits, is used in conjunction with the onlyContains function.

integer isNumeric(string a)
{
   return onlyContains(a,NUMBERS);
}

    This function allows a script to quickly determine whether a string is numeric.

Understanding the isAlpha Function

    The isAlpha function determines whether the specified string is a set of only letter. Either capital or lowercase is acceptable. The isAlpha function works by ensuring that the string only contains characters from the LETTERS string.

integer isAlpha(string a)
{
   return onlyContains(a,LETTERS);
}

    This function allows a script to quickly determine whether a string only contains letters.

Understanding the isAlphanumeric Function

    The isAlphanumeric function determines whether the specified string is a set of only letters and digits. Either capital or lowercase is acceptable. The isAlphanumeric function works by ensuring that the string only contains characters from the LETTERS or NUMBERS strings.

integer isAlphanumeric(string a)
{
   return onlyContains(a,LETTERS + NUMBERS);
}

    This function allows a script to quickly determine whether a string contains only digits and letters.

Testing String Sets

    The script includes a simple state_entry function that tests the functions presented in this recipe. This shows how the functions in this recipe behave when passed various types of data.

default
{
    state_entry()
    {
        llSay(0,"isNumeric(abc): " + (string)isNumeric("abc") );
        llSay(0,"isNumeric(123): " + (string)isNumeric("123") );
        llSay(0,"isAlpha(abc): " + (string)isAlpha("abc") );
        llSay(0,"isAlpha(123): " + (string)isAlpha("123") );
        llSay(0,"isAlphanumeric(abc123): " + (string)isAlphanumeric("abc123") );
        llSay(0,"isAlphanumeric(123!!!!): " + (string)isAlphanumeric("123!!!!") );
    }
} 

    When run the above code will produce the following output.

[3:24]  Object: isNumeric(abc): 0
[3:24]  Object: isNumeric(123): 1
[3:24]  Object: isAlpha(abc): 1
[3:24]  Object: isAlpha(123): 0
[3:24]  Object: isAlphanumeric(abc123): 1
[3:24]  Object: isAlphanumeric(123!!!!): 0

    It is also possible to parse strings. This will be discussed in the next section.

Copyright 2005-2009 by Heaton Research, Inc.