Here are a three string utility functions
by Matthew Langley · in Torque Game Builder · 04/22/2005 (5:01 pm) · 15 replies
ReturnStringBefore("string-test", "-");
would return "string"
returnStringAfter("string-test", "-");
would return "test"
getTagName("");
would return "tag"
just some examples on how to disect strings :) use these in my Torque DB to parse and ran accross another need for them so figured I'd post them as reference
would return "string"
returnStringAfter("string-test", "-");
would return "test"
getTagName("
would return "tag"
just some examples on how to disect strings :) use these in my Torque DB to parse and ran accross another need for them so figured I'd post them as reference
function returnStringAfter(%string, %char)
{
%endChar = strLen(%string);
for(%i=0;%i<%endChar;%i++)
{
%charToCheck = getSubStr(%string, %i, 1);
if(%charToCheck $= %char)
{
%startChar = %i + 1;
}
}
%totalChar = %endChar - %startChar;
%stringToReturn = getSubStr(%string, %startChar, %totalChar);
return %stringToReturn;
}
function returnStringBefore(%string, %char)
{
%endChar = strLen(%string);
for(%i=0;%i<%endChar;%i++)
{
%charToCheck = getSubStr(%string, %i, 1);
if(%charToCheck $= %char)
{
%startChar = %i;
}
}
%totalChar = %startChar;
%stringToReturn = getSubStr(%string, 0, %totalChar);
return %stringToReturn;
}
function getTagName(%string)
{
%endChar = strLen(%string);
%firstChar = getSubStr(%string, 0, 1);
if(%firstChar $= "<")
{
%totalChar = %endChar - 2;
} else
{
%totalChar = %endChar - 1;
}
%stringToReturn = getSubStr(%string, 1, %totalChar);
return %stringToReturn;
}About the author
Was a GG Associate and then joined GG in 2005. Lead tool dev for T2D and T3D. In 2011 joined mobile company ngmoco/DeNA and spent about 4 years working game and server tech. 2014 joined startup Merigo Games developing server technology.
#2
Things like explode are so convenient.
04/23/2005 (4:02 pm)
Someday I want to implement the PHP string functons into TAP. PHP has some of the best string hsandling i've ever seen.Things like explode are so convenient.
#3
I agree John
explode is great... my favorite is
amazingly easy to replace things in a whole document quick
04/23/2005 (4:22 pm)
Thx for the heads up Stephen... I think your right... though it might be much more complex than mine, might handle the MLText tags... I need to look that up...I agree John
explode is great... my favorite is
Quote:
$bad_chars= array("\\", "'", "\"");
$good_chars = array("\\\\", "''", "\"\"");
return str_replace($bad_chars, $good_chars, $strTemp);
amazingly easy to replace things in a whole document quick
#4
%PlayerAcccountInfo = "PAI|Active|||Stephen Zepp|3333-4444-5555-6666|";
The "PAI" means that this would be the "Player Account Info" data set, and the sender and receiver agree on a consistent positional index for various fields: the first field in this example would be the account status, the fourth "field" in this example is "Player Name", the 5th is "Credit Card Number".
What's neat is that TCL allows you to split a string into a list, and then you have an entire set of functions that can be performed on lists, including search, indexing, replacement, etc.
(psuedo code follows, using TAPScript instead of TCL syntax):
%PlayerAccountInfoFields = listSplit(%PlayerAccountInfo, "|");
%PlayerName = listIndex(%playerAccountInfoFields, 4);
%playerCCNumber = listIndex(%playerAccountInfoFields, 5);
%playerAccountStatus = "Disabled"; // disabled account
%PlayerAccountInfoFields = listReplace(%PlayerAccountInfoFields, %playerAccountStatus, 1);
%playerAccountInfo = listJoin(%PlayerAccountInfoFields, "|");
It makes for an extremely efficient data protocol for bandwidth purposes, and once you become familiar with the field associations, relatively human-readible as well.
04/23/2005 (4:27 pm)
TCL has some very nifty techniques for handling generic formats that have consistent separators as well. There is a data format in healthcare IT called "HL7", which utilizes a "relative-positional index" concept, where a particular data field is valued based on it's position within a particular block of similar data, and fields are separated by a consistent "field separator" character. For example:%PlayerAcccountInfo = "PAI|Active|||Stephen Zepp|3333-4444-5555-6666|";
The "PAI" means that this would be the "Player Account Info" data set, and the sender and receiver agree on a consistent positional index for various fields: the first field in this example would be the account status, the fourth "field" in this example is "Player Name", the 5th is "Credit Card Number".
What's neat is that TCL allows you to split a string into a list, and then you have an entire set of functions that can be performed on lists, including search, indexing, replacement, etc.
(psuedo code follows, using TAPScript instead of TCL syntax):
%PlayerAccountInfoFields = listSplit(%PlayerAccountInfo, "|");
%PlayerName = listIndex(%playerAccountInfoFields, 4);
%playerCCNumber = listIndex(%playerAccountInfoFields, 5);
%playerAccountStatus = "Disabled"; // disabled account
%PlayerAccountInfoFields = listReplace(%PlayerAccountInfoFields, %playerAccountStatus, 1);
%playerAccountInfo = listJoin(%PlayerAccountInfoFields, "|");
It makes for an extremely efficient data protocol for bandwidth purposes, and once you become familiar with the field associations, relatively human-readible as well.
#5
looks like almost identical functions as php... I like that
04/23/2005 (4:40 pm)
Hmm very cool...looks like almost identical functions as php... I like that
#6
The big advantage however is that it's damned fast, and extremely minimal data is sent for changing just a few fields, all the way up to changing a ton of fields--tags and /tags can get really expensive bandwidth wise if they are fully human readable.
04/23/2005 (5:05 pm)
The big disadvantage with this type of system is that it is "static", in that the sender and receiver both need to be exactly aware of all the fields in the datasets, and what they are used for. XML for example is "run time decodable", since you actually have tags.The big advantage however is that it's damned fast, and extremely minimal data is sent for changing just a few fields, all the way up to changing a ton of fields--tags and /tags can get really expensive bandwidth wise if they are fully human readable.
#7

figured I'd share
you call it like this
%val = explode("blah1|blah2|blah3", "|");
then it ruturns a script object like this
%val.contents[0] = blah1
%val.contents[2] = blah2
%val.contents[3] = blah3
%val.count = 3
04/28/2005 (9:34 am)
Well I found the need for a simple explode like function...figured I'd share
you call it like this
%val = explode("blah1|blah2|blah3", "|");
then it ruturns a script object like this
%val.contents[0] = blah1
%val.contents[2] = blah2
%val.contents[3] = blah3
%val.count = 3
function explode(%string, %char)
{
if(!isObject(explode))
new ScriptObject(explode);
%explodeCount = 0;
%lastFound = 0;
%endChar = strLen(%string);
for(%i=0;%i<%endChar;%i++)
{
%charToCheck = getSubStr(%string, %i, 1);
if(%charToCheck $= %char)
{
explode.contents[%explodeCount] = getSubStr(%string, %lastFound, (%i-%lastFound));
%lastFound = %i + 1;
%explodeCount++;
}
}
explode.contents[%explodeCount] = getSubStr(%string, %lastFound, (%i-%lastFound));
explode.count = %explodeCount + 1;
return explode;
}
#8
04/28/2005 (9:41 am)
I think getField might have worked also...
#9
maybe if I exposed the getUnit(s) command I could have more control
through right now a script function works for more control
04/28/2005 (9:55 am)
Hmm thanks, seems like that will do itecho(getField("blah\tblah2\tblah3", "0"));returns blah.... "1" returns blah2... it seperates it by \t\nmaybe if I exposed the getUnit(s) command I could have more control
through right now a script function works for more control
#10
Heres a function you can add in script to add a "getObjectByName" function to SimSets
heres how I tested it
it echoed the ScriptObject's ID :)
07/08/2005 (11:58 am)
(Might as well add any other useful script functions here :)Heres a function you can add in script to add a "getObjectByName" function to SimSets
function SimSet::getObjectByName(%this, %name)
{
%count = %this.getCount();
for(%i=0;%i<%count;%i++)
{
%obj = %this.getObject(%i);
if(%obj.getName() $= %name)
return %obj;
}
return -1;
}heres how I tested it
new ScriptObject(SO);
new SimSet(SS);
SS.add(SO);
echo(SS.getObjectByName("SO"));it echoed the ScriptObject's ID :)
#11
This also seems to work and no (script-side) iteration... Do you have any serious code to test this on?
07/08/2005 (4:31 pm)
@Matt:This also seems to work and no (script-side) iteration... Do you have any serious code to test this on?
function SimSet::getObjectByName(%this, %name)
{
if( isObject( %name ) )
{
%id = %name.getId();
return %this.isMember( %id ) ? %id : -1;
}
return -1;
}
new ScriptObject(SO);
new ScriptObject(GO);
new ScriptObject(YAO);
new SimSet(SS);
SS.add(SO);
SS.add(GO);
SS.add(YAO);
// Find the objects by name
echo(SS.getObjectByName("SO"));
echo(SS.getObjectByName("GO"));
echo(SS.getObjectByName("YAO"));
// And if it's not in there
echo(SS.getObjectByName("NO"));
#12
07/15/2005 (7:32 am)
Thank you! these are going into my permanent functions block!
#13
@Matthew
When dealing with arrays within Scriptobjects, do you need to delete the object explicity, or if it's assigned to a local would it be deleted when it's out of scope? ( I remember reading something on the other forums about arrays and script/simobjects needed to be specifically deleted...)
thanks!
07/15/2005 (7:34 am)
Newbie question for @Matthew
When dealing with arrays within Scriptobjects, do you need to delete the object explicity, or if it's assigned to a local would it be deleted when it's out of scope? ( I remember reading something on the other forums about arrays and script/simobjects needed to be specifically deleted...)
thanks!
#14
@Colleen: "ScriptObject arrays" (thats what I always call them) is a bit of a misconception. ScriptObjects really are objects, like a sprite, or sceneobject. They have a unique "ID."... now when I create a scripobject like this
%obj = new ScriptObject();
all it really is doing is putting the reference ID of the scriptObject into %obj. So when the %obj variable leaves "scope" and is destroyed the script object still exists but now can only be referenced by its "ID" number which is lost since I never stored it in anything else...
In short you must delete them
%obj.delete();
hope that explains why :)
07/15/2005 (8:23 am)
@Brian: Completely correct. In fact I originally created that in using a sub value instead of the actual name, like %obj.type since in my scripting I usually run off of sub values like that, but for the example I did that for (in another Torque forum) I used the name... you are definately correct though, that would be a much more efficient way of .getObjectByName().@Colleen: "ScriptObject arrays" (thats what I always call them) is a bit of a misconception. ScriptObjects really are objects, like a sprite, or sceneobject. They have a unique "ID."... now when I create a scripobject like this
%obj = new ScriptObject();
all it really is doing is putting the reference ID of the scriptObject into %obj. So when the %obj variable leaves "scope" and is destroyed the script object still exists but now can only be referenced by its "ID" number which is lost since I never stored it in anything else...
In short you must delete them
%obj.delete();
hope that explains why :)
#15
e.g.
This would definitely be a problem for those using named objects for the namespace they create.
Be warned, use Matt's version instead!
07/30/2005 (11:50 am)
As a follow up, it occurred to me that the version of "getObjectByName ()" I suggested fails if names are not globally unique :-(e.g.
new SimSet(SS);
new ScriptObject(YO);
SS.add(YO);
new ScriptObject(YO){ msg = "I'm not YO, I just look like him!";};
echo(SS.getObjectByName("YO"));This would definitely be a problem for those using named objects for the namespace they create.
Be warned, use Matt's version instead!
Torque 3D Owner Stephen Zepp