Difference between revisions of "LlParseStringKeepNulls"

From Second Life Wiki
Jump to navigation Jump to search
m (Added footnote to 'Caveats')
m (<lsl> tag to <source>)
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{LSL_Function
{{LSL_Function
|func_id=285|func_sleep=0.0|func_energy=10.0
|func_id=285|func_sleep=0.0|func_energy=10.0
|func=llParseStringKeepNulls|return_type=list|p1_type=string|p1_name=src|p2_type=list|p2_name=separators|p3_type=list|p3_name=spacers
|func=llParseStringKeepNulls
|func_footnote='''separators''' and '''spacers''' must be lists of strings, maximum of 8 each.
|return_type=list
|p1_type=string|p1_name=src|p1_desc=source string
|p2_type=list|p2_name=separators|p2_desc=separators to be discarded
|p3_type=list|p3_name=spacers|p3_desc=spacers to be kept
|func_footnote
|func_desc
|func_desc
|return_text=that is '''src''' broken into a list, discarding '''separators''', keeping '''spacers''', keeping any null values generated.
|return_text=that is {{LSLP|src}} broken into a list, discarding {{LSLP|separators}}, keeping {{LSLP|spacers}}, keeping any null values generated.
|spec
|spec=
|caveats=*Every element in the list will be a string, no matter what you think it should be. Cast the results of llList2String to get what you want.
The behavior is identical to that for [[llParseString2List]], except blank strings found in the list are kept. This is useful when parsing a list that contains values that can be null or empty (and subsequently removing the nulls would upset the distribution of data and the element indexes).
** ''integer my_int = (integer)llList2String(my_list,i);''


[[llList2String]] is used in this example, as [[llList2Integer]] can only handle integers in simple notation, ie. will not handle hexadecimal integers.  
llParseStringKeepNulls("", ["~"], []) will return [""]
|caveats=
* Only the first 8 {{LSLP|separators}} and first 8 {{LSLP|spacers}} will be used any extras will be ignored.
* All {{LSLP|separators}} and {{LSLP|spacers}} must be strings, all other types will be ignored.
* {{LSLP|separators}} take precedent over {{LSLP|spacers}}. The string is parsed from start to finish, each position is compared against the {{LSLP|separators}} then {{LSLP|spacers}} before moving onto the next position. The first match is the one that is returned. Using the list ["A", "AB"] will always act with "A" and never "AB".
* Duplicate or irrelevant {{LSLP|separators}} or {{LSLP|spacers}} count towards the limits and slow down parsing.
* All entries in the return are typed as string. Use explicit typecasting on [[llList2String]] to convert the values into other types. Do not rely upon the implicit typecasting of the other llList2* functions (as they typically return a default value).
* Remember to capture the result of the operation with a variable, unless you are planning to act directly on the results.
|constants
|constants
|examples=<pre>default
|examples=<source lang="lsl2">default
{
{
     state_entry()
     state_entry()
Line 26: Line 36:
         llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
         llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
     }
     }
}</pre>
}</source>
|helpers=<div id="box">
|helpers=
{{#vardefine:p_src_desc|source string
'''Replacement functions without or very large separator/spacer count limits'''
}}{{#vardefine:p_separators_desc|separators to be discarded
{{{!}}
}}{{#vardefine:p_spacers_desc|spacers to be kept}}
{{LSL DefineRow||[[ParseString2List]]|Functions exactly the same as [[llParseString2List]] and [[llParseStringKeepNulls]].}}
{{#vardefine:p_KeepNulls_desc|TRUE}}
{{LSL DefineRow||[[Separate Words|separateWords]]|Functions the same as [[llParseString2List]] unless certain preconditions are not met.}}
== Function: [[list]] ParseString2List([[string]] {{LSL Param|src}},[[list]] {{LSL Param|separators}},[[list]] {{LSL Param|spacers}},[[integer]] {{LSL Param|KeepNulls}}); ==
{{!}}}
<div style="padding: 0.5em;">
|also_functions={{LSL DefineRow||[[llParseString2List]]}}
Returns a list that is '''{{LSL Param|src}}''' broken into a list, discarding '''{{LSL Param|separators}}''', keeping '''{{LSL Param|spacers}}''', keeps any null values generated (set '''{{LSL Param|KeepNulls}}''' value [[TRUE]]).
{{LSL DefineRow||[[llDumpList2String]]}}
 
{{LSL DefineRow||[[llCSV2List]]}}
Same as '''[[llParseStringKeepNulls]]''', but not limited to 8 spacers or separators.  
{{LSL DefineRow||[[llList2CSV]]}}
 
Thus substitute a call to the '''[[llParseStringKeepNulls]]''' function by a call to '''ParseString2List''' whenever you have more than 8 separators or more than 8 spacers.
<pre>
list ParseString2List(string src, list separators, list spacers, integer ParseStringKeepNulls)
{//works just like llParseString2List and llParseStringKeepNulls but without
//the limits on spacers or separators
    list keys;
    integer i = spacers != [];
    integer offset;
    integer test;
    list out;
    string p;
    while(i)
        if((p = llList2String(spacers, i = ~-i)))
        {
            if(~(offset = llListFindList(out, (list)p)))
                keys = llListReplaceList(keys, (list)(~i), offset = -~(offset << 1), offset);
            else if(~(test = llSubStringIndex(src, p)))
            {
                keys = test + ((~i) + keys);
                out = p + out;
            }
        }
    for(i = separators != [];i;)
        if((p = llList2String(separators, i = ~-i)))
        {
            if(~(offset = llListFindList(out, (list)p)))
                keys = llListReplaceList(keys, (list)i, offset = -~(offset << 1), offset);
            else if(~(test = llSubStringIndex(src, p)))
            {
                keys = test + (i + keys);
                out = p + out;
            }
        }
    out = [];
    offset = 0;
    while(keys)
    {
        list t = llList2List(llListSort(keys, 2, TRUE), 0, 1);
        integer r = llListFindList(keys, t);
        if((i = llList2Integer(t, 0)) < offset)
            keys = llDeleteSubList(keys, r, -~r);
        else
        {
            if(offset != i || ParseStringKeepNulls)
                out += llDeleteSubString(src, i - offset, -1);
            if(0x80000000 & test = llList2Integer(t, 1))
                out += p = llList2String(spacers, ~test);
            else
                p = llList2String(separators, test);
            src = llDeleteSubString(src, 0, ~(offset - (i += llStringLength(p))));
            offset = i;
            if(~(test = llSubStringIndex(src, p)))
                keys = llListReplaceList(keys, (list)(test + offset), r, r);
            else
                keys = llDeleteSubList(keys, r, -~r);
        }
    }
    if(src != "" || ParseStringKeepNulls)
        return out + src;
    return out;
}//Strife Onizuka</pre></div></div>
|also_functions=*{{LSLG|llParseString2List}}
*{{LSLG|llDumpList2String}}
*{{LSLG|llCSV2List}}
*{{LSLG|llList2CSV}}
|also_events
|also_events
|also_tests
|also_tests
|also_articles
|also_articles
|notes
|notes
|permission
|negative_index
|sort=ParseStringKeepNulls
|sort=ParseStringKeepNulls
|cat1=List
|cat1=List

Latest revision as of 14:09, 22 January 2015

Summary

Function: list llParseStringKeepNulls( string src, list separators, list spacers );

Returns a list that is src broken into a list, discarding separators, keeping spacers, keeping any null values generated.

• string src source string
• list separators separators to be discarded
• list spacers spacers to be kept

Specification

The behavior is identical to that for llParseString2List, except blank strings found in the list are kept. This is useful when parsing a list that contains values that can be null or empty (and subsequently removing the nulls would upset the distribution of data and the element indexes).

llParseStringKeepNulls("", ["~"], []) will return [""]

Caveats

  • Only the first 8 separators and first 8 spacers will be used any extras will be ignored.
  • All separators and spacers must be strings, all other types will be ignored.
  • separators take precedent over spacers. The string is parsed from start to finish, each position is compared against the separators then spacers before moving onto the next position. The first match is the one that is returned. Using the list ["A", "AB"] will always act with "A" and never "AB".
  • Duplicate or irrelevant separators or spacers count towards the limits and slow down parsing.
  • All entries in the return are typed as string. Use explicit typecasting on llList2String to convert the values into other types. Do not rely upon the implicit typecasting of the other llList2* functions (as they typically return a default value).
  • Remember to capture the result of the operation with a variable, unless you are planning to act directly on the results.
All Issues ~ Search JIRA for related Bugs

Examples

default
{
    state_entry()
    {
        // This will say:
        // <A><crazy><fox><.><Saw><the><moon><.><.>
        string my_string = "A crazy fox.  Saw the moon..";
        list my_list = llParseString2List(my_string,[" "],["."]);
        llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
        
        // This will say:
        //  <A><crazy><fox><.><><><Saw><the><moon><.><><.><>
        my_list = llParseStringKeepNulls(my_string,[" "],["."]);
        llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
    }
}

Useful Snippets

Replacement functions without or very large separator/spacer count limits

•  ParseString2List Functions exactly the same as llParseString2List and llParseStringKeepNulls.
•  separateWords Functions the same as llParseString2List unless certain preconditions are not met.

See Also

Functions

•  llParseString2List
•  llDumpList2String
•  llCSV2List
•  llList2CSV

Deep Notes

Search JIRA for related Issues

Signature

function list llParseStringKeepNulls( string src, list separators, list spacers );