PDA

View Full Version : String.Format()



MichaelxxOA
February 28th, 2006, 02:39 PM
This is another one of those utilities that my work requires... well actually it doesn't I just do this for convenience...

used when concatenating strings with values... I'm going to use a url as an example.

Say we have a variable for our url, and the text to display...

ActionScript Code:

var url = "http://www.kirupa.com";
var label = "kirupa's Great Website";






the way you'd bulid a link out of this would look something like...

ActionScript Code:

var linkHtml = "<a href='" + url + "'>" + label + "</a>";





Now this will work fine, but it's ugly, and can get to be not fun when working with complicated insertions. Luckily as a C# developer I have the luxury of using something called the String.Format() method which allows us to do this...

build our string...

ActionScript Code:

var url = "http://www.kirupa.com";
var label = "Kirupa's Great Website";
var linkHtml = "<a href='{0}'>{1}</a>";

var final_html = stringFormatter(linkHtml, url, label);




The syntax is String.Format(string, args);

you'll notice in our string, we have {0} and {1}.. these are our replacement markers... and our args are the arguments to replace... in our example...

url is argument0 and label is argument1, so anywhere we see {0} it will be replaced with argument0 (url) and anywhere we see {1} it will be replaced with argument1 (label)... we can do this with as many arguments as we'd like.

I hope that some of this came in clear, here's the class



// this is a class we will use to transform strings
// it will grow as we see fit.
// for the most part just a method library geared towards
// strings specifically

/*
*
*@author Michael Avila
*@version 1.3
*@description This is a class for handling strings.
*/
class StringUtility
{

/* Replaces all occurances of one series of characters with another series of characters
*
* @param The string you are invoking the replace on.
* ...
* @param The series of characters which you plan on replacing
* ...
* @param The series of characters you are replacing with.
*
* @return The string with our values replaced
*
* @usage <pre>StringUtility.replace("Hello World", "World", "Michael");</pre>
*/
public static function replace(original : String, string1 : String, string2 : String) : String
{
var return_string : String = "";

var start_position : Number = 0;
var end_position : Number = 0;

while (true)
{
start_position = original.indexOf(string1, end_position);

if (start_position == -1) break;

return_string += original.substring(end_position, start_position);
return_string += string2;

end_position = start_position + string1.length;
}

return_string += original.substring(end_position, original.length);

return return_string;
}

/* Returns whether or not your series of characters is contained within this string
* @param The string you are going to be looking in
* ...
* @param The strings of characters that you will be looking for.
*
* @return Returns true if all the specified arguments are contained in the string
* and false if not.
*
* @usage <pre>StringUtility.contains("this is the search string", "this", "search");</pre>
*/
// checks whether or not a string contains a specific series of characters

public static function contains(the_string : String, args : String) : Boolean
{
// how many different strings are we checking for...
var strings : Number = arguments.length-1;

// loop through how many we are checking for, and
for (var i:Number=0; i<strings; i++)
{
if (the_string.indexOf(arguments[i+1]) == -1)
{
// if the string does not contain what we asked for.
return false;
}
}

// if we get this far, then the string did contain everything we asked for...
return true;
}

/* Inserts values into a string.
* @param The string you are going to be inserting values into
* ...
* @param The values that you will be adding into the string
*
* @return Returns the string with all of your values inserted
*
* @usage <pre>StringUtility.insertion("Hello: {0}, this is visit number {1}.", "Michael", "20");</pre>
*
*/
public static function insertion (original : String, args : String ) : String
{
// some constants.. what are markers tags are...
var MARKER_OPEN : String = "{";
var MARKER_CLOSE : String = "}";
// The string with all the values set...
var new_string : String = "";
// represents our current search position of the character {
var position_1 : Number = null;
// represents our current search position of the character }
var position_2 : Number = null;
// the number that represents the marker (argument) value that we are currently on
var argument : Number = 0;
// the string we are replacing our argument with
var argumentValue : String = "";
while (true)
{
// the position we are searching from...
var search_from : Number;
// if the position has not been set, start from the beginning
if (position_1 == null)
{
search_from = 0;
} else
{
search_from = position_1 + 1;
}
// set position to the next index of the next instance of our MARKER_OPEN
position_1 = original.indexOf (MARKER_OPEN, search_from);
// if there are no more instances of MARKER_OPEN in this string, then break from the loop
if (position_1 == - 1) break;

// where we will begin the slicing of our string at... start at 0
var start : Number = 0;
// where we will end the slicing of our string at... end at position_1
var end : Number = position_1;
// if position_2 has been set, then start is always the character index AFTER position_2
if (position_2 != null)
{
start = position_2 + 1;
}
// add to new_string the contents between this and the last marker
// if this is the first marker then it just adds from the beginning of the string
new_string += original.substring (start, end);

// set position_2 to the index of MARKER_CLOSE after our current MARKER_OPEN
position_2 = original.indexOf (MARKER_CLOSE, position_1);
// parse the argument as an integer.. requires string manipulation to pull the marker
// value out.
argument = parseInt (original.substring (position_1 + 1, position_2));
// pull from the arguments array the value that will replace this marker...
argumentValue = arguments [argument + 1];
// add our argument value, so that our new_string no longer contains a marker, but
// instead the value
new_string += argumentValue;

}
// when we are done, there are no more markers, so just add on the remainder
// of our original string from the last marker on, onto our new_string
new_string += original.substring (original.lastIndexOf (MARKER_CLOSE) + 1, original.length);
// return our string with all the inserted values
return new_string;
}
}




******* UPDATED
Now has contains and replace methods... and a documentation...


www.nowtheworld.com/ASDocs/StringUtility

Take Care.

_michael

LunaSolar
February 28th, 2006, 02:47 PM
That went over my head so fast I think I got whiplash trying to watch it.

MichaelxxOA
February 28th, 2006, 02:57 PM
hehe, what did you not understand?

LunaSolar
February 28th, 2006, 03:18 PM
Take is as a compliment, really. You just came out with that conversationally and it's like German to me.

I never even understood what it was supposed to actually do.

MichaelxxOA
February 28th, 2006, 03:30 PM
hehe, alright, it's made for string insertions. Say you have a string that you want to insert values into.. like... for instance you build an app where the user can make their own custom urls. Well you know exactly what a url looks like, <a href="url">display_text</a>. The problem is that you don't know what the url or the display_text is going to be. In this case you'd want to insert your own values into something that you already knew the surrounding format.

Now instead of doing insertions usually when you have a situation like this you'd just build around values, for instance you would build the url with the url and label variables as...


var link = "<a href='" + url + "'>" + label + "</a>";

This will work fine but it gets complicated, and not so easy to change. So what my little function does is this, you pass in a string with markers as to where insertions will be made.


var link_str = "<a href='{0}'>{1}</a>";
Here you know that you will be inserting values at markers {0} and {1}, well the function takes in arguments like so...


stringFormatter( stringToFormat, args )

The args are the values that will replace {0} and {1} and {2}.. for as many as you have. So in our case...



var url = "http://www.kirupa.com";
var label = "Kirupa's Great Website";
var link = stringFormatter("<a href='{0}'>{1}</a>", url, label);


here we pass in the string "<a href='{0}'>{1}</a>" with it's markers {0} and {1}. We also pass in the values that {0} and {1} represent which are url and label. If we would like to add another insertion in there it would be as simple as...



var greeting = "Hello: {0}";
var name = "Michael";
var final_greeting = stringFormatter(greeting, name);

// or

var string_rp = "var0: {0}, var1: {1}, var2: {2}, var3: {3}, var4: {4}";
var final = stringFormatter(string_rp, "Hello", "My", "Name", "Is", "Michael");
trace(final);


Was this a little better? Take Care.

_michael

code again...





var s = stringFormatter("<a href='{0}'>{1}</a>", "http://www.createage.com", "Michael's Site");

trace(s);

function stringFormatter(original:String, args1:Object):String
{
var new_string:String = "";

var position:Number = 0;
var second_position:Number = 0;
var prev_position:Number = 0;

while(true)
{
prev_position = second_position;
// positions
var argument:Number = 0;
var argumentString:String = "";
var argumentValue:String = "";



position = original.indexOf("{", position+1);
// if there is no more { then break from this loop
if (position == -1) break;

var start:Number;
if (prev_position != 0)
{
start = prev_position+1;
}
var end:Number = position;

new_string += original.substring(start, end);
second_position = original.indexOf("}", position);

argument = parseInt(original.substring(position+1, second_position));
argumentValue = arguments[argument+1];

new_string += argumentValue;
}
new_string += original.substring(prev_position+1, original.length);

return new_string;
}

smoothhabitat
February 28th, 2006, 04:29 PM
right on. it'd be cool if you could do a replacement with string names like this though

var linkHtml = "<a href='{mySource}'>{myLabel}: {mySource}</a>";

or whatever.

MichaelxxOA
February 28th, 2006, 04:46 PM
yeah, sort of like a Smarty set up from php... this is more just to replicate the String.Format() of C#, although not a bad idea.

_Michael

28bit
March 1st, 2006, 05:10 AM
This is real nice. Thanks a bunch for sharing. :D

Seb Hughes
March 1st, 2006, 08:14 AM
Take is as a compliment, really. You just came out with that conversationally and it's like German to me.

I never even understood what it was supposed to actually do.

Its like english to me. German doesnt look anything like that ;)

LunaSolar
March 1st, 2006, 09:49 AM
Wow, I get it now. That is sweet.

MichaelxxOA
March 1st, 2006, 01:14 PM
Thanks, I have no problem sharing this little stuff. I'm glad you get it nos LunaSolar, and last but not least Seb is right, it's not german.

_Michael

MichaelxxOA
March 1st, 2006, 02:29 PM
Okay I took the time to throw this into a string utility class... I'm not sure how possible it is going to be to add to this, but hell why not... here's the code listing for the class, and how you'd use it in your fla at the bottom. Enjoy, and take care.

_Michael

StringUtility.as:



// this is a class we will use to transform strings
// it will grow as we see fit.
// for the most part just a method library geared towards
// strings specifically
class StringUtility
{
// inserts values into a string
public static function insertion (original : String, args : String ) : String
{
// some constants.. what are markers tags are...
var MARKER_OPEN : String = "{";
var MARKER_CLOSE : String = "}";
// The string with all the values set...
var new_string : String = "";
// represents our current search position of the character {
var position_1 : Number = null;
// represents our current search position of the character }
var position_2 : Number = null;
// the number that represents the marker (argument) value that we are currently on
var argument : Number = 0;
// the string we are replacing our argument with
var argumentValue : String = "";
while (true)
{
// the position we are searching from...
var search_from : Number;
// if the position has not been set, start from the beginning
if (position_1 == null)
{
search_from = 0;
} else
{
search_from = position_1 + 1;
}
// set position to the next index of the next instance of our MARKER_OPEN
position_1 = original.indexOf (MARKER_OPEN, search_from);
// if there are no more instances of MARKER_OPEN in this string, then break from the loop
if (position_1 == - 1) break;

// where we will begin the slicing of our string at... start at 0
var start : Number = 0;
// where we will end the slicing of our string at... end at position_1
var end : Number = position_1;
// if position_2 has been set, then start is always the character index AFTER position_2
if (position_2 != null)
{
start = position_2 + 1;
}
// add to new_string the contents between this and the last marker
// if this is the first marker then it just adds from the beginning of the string
new_string += original.substring (start, end);

// set position_2 to the index of MARKER_CLOSE after our current MARKER_OPEN
position_2 = original.indexOf (MARKER_CLOSE, position_1);
// parse the argument as an integer.. requires string manipulation to pull the marker
// value out.
argument = parseInt (original.substring (position_1 + 1, position_2));
// pull from the arguments array the value that will replace this marker...
argumentValue = arguments [argument + 1];
// add our argument value, so that our new_string no longer contains a marker, but
// instead the value
new_string += argumentValue;

}
// when we are done, there are no more markers, so just add on the remainder
// of our original string from the last marker on, onto our new_string
new_string += original.substring (original.lastIndexOf (MARKER_CLOSE) + 1, original.length);
// return our string with all the inserted values
return new_string;
}
}



FLA Usage:



var s = StringUtility.insertion("<a href='{0}'>{1}</a>", "http://www.createage.com", "Michael's Site");

trace(s);

bombsledder
March 1st, 2006, 08:56 PM
cool class, never even really thought to make something like this lol, maybe you could add a search function to it, since flash doesn't really have a known search function, if(mystr.Search("smile")){trace("was found in the text")} would be so much easier, then using the indexOf() function, =( and maybe it can return an array of how many smiles were found, and the indexs of each start to end, that would be pretty cool lol, i'll probably make this class now

MichaelxxOA
March 1st, 2006, 10:04 PM
yeah, it's already implemented but it's called contains.. let me post new code when I get back.. Take Care.

_Michael

MichaelxxOA
March 1st, 2006, 10:19 PM
Here is an update, with the contains() method...



// this is a class we will use to transform strings
// it will grow as we see fit.
// for the most part just a method library geared towards
// strings specifically
class StringUtility
{

// checks whether or not a string contains a specific series of characters
public static function contains(the_string : String, args : String) : Boolean
{
// how many different strings are we checking for...
var strings : Number = arguments.length-1;

// loop through how many we are checking for, and
for (var i:Number=0; i<strings; i++)
{
if (the_string.indexOf(arguments[i+1]) == -1)
{
// if the string does not contain what we asked for.
return false;
}
}

// if we get this far, then the string did contain everything we asked for...
return true;
}

// inserts values into a string
public static function insertion (original : String, args : String ) : String
{
// some constants.. what are markers tags are...
var MARKER_OPEN : String = "{";
var MARKER_CLOSE : String = "}";
// The string with all the values set...
var new_string : String = "";
// represents our current search position of the character {
var position_1 : Number = null;
// represents our current search position of the character }
var position_2 : Number = null;
// the number that represents the marker (argument) value that we are currently on
var argument : Number = 0;
// the string we are replacing our argument with
var argumentValue : String = "";
while (true)
{
// the position we are searching from...
var search_from : Number;
// if the position has not been set, start from the beginning
if (position_1 == null)
{
search_from = 0;
} else
{
search_from = position_1 + 1;
}
// set position to the next index of the next instance of our MARKER_OPEN
position_1 = original.indexOf (MARKER_OPEN, search_from);
// if there are no more instances of MARKER_OPEN in this string, then break from the loop
if (position_1 == - 1) break;

// where we will begin the slicing of our string at... start at 0
var start : Number = 0;
// where we will end the slicing of our string at... end at position_1
var end : Number = position_1;
// if position_2 has been set, then start is always the character index AFTER position_2
if (position_2 != null)
{
start = position_2 + 1;
}
// add to new_string the contents between this and the last marker
// if this is the first marker then it just adds from the beginning of the string
new_string += original.substring (start, end);

// set position_2 to the index of MARKER_CLOSE after our current MARKER_OPEN
position_2 = original.indexOf (MARKER_CLOSE, position_1);
// parse the argument as an integer.. requires string manipulation to pull the marker
// value out.
argument = parseInt (original.substring (position_1 + 1, position_2));
// pull from the arguments array the value that will replace this marker...
argumentValue = arguments [argument + 1];
// add our argument value, so that our new_string no longer contains a marker, but
// instead the value
new_string += argumentValue;

}
// when we are done, there are no more markers, so just add on the remainder
// of our original string from the last marker on, onto our new_string
new_string += original.substring (original.lastIndexOf (MARKER_CLOSE) + 1, original.length);
// return our string with all the inserted values
return new_string;
}
}


Alright, so there's a little bit of explaining I gotta do... the first thing is that our new contains method is not tied down to checking if only 1 series of characters exists... the arguments you pass in are this...

the string you're searching through, and then the rest of your arguments are what we are checking if it contains... this method will return false if ANY of the arguments you pass in are not contained inside of the String you pass in. If they are all in there, it will return true.

By allowing you to pass in multiple arguments to check through, I think I have boosted usability and just all around cleanliness... Take Care, and enjoy.

here's how you would use it in an fla...



var s = StringUtility.insertion("{1}: <a href='{0}'>{1}</a>", "http://www.createage.com", "Michael's Site");

trace (StringUtility.contains(s, "<a href=", "http://www.createage.com"));


_Michael

bombsledder
March 2nd, 2006, 06:57 AM
yup, thats it lol, such an easy code to make saves people alot of time rewriting code, i think there should be a libraries thread, were people can post there classe/interfaces (don't know why there isnt =()

MichaelxxOA
March 3rd, 2006, 03:19 AM
Here is some documentation.. oooo....

http://www.nowtheworld.com/ASDocs/StringUtility/

enjoy

phorte
March 3rd, 2006, 03:49 AM
Now that is very cool. Nice work. Ive been attempting to make a Number Formater, putting in leading zero's and decimal points etc, this might actually give me a bit of a base to work from. Thanks man.

-Aussie Devil

MichaelxxOA
March 3rd, 2006, 04:59 AM
Never a problem, I'm actually working on a very similar thing at the moment... I really want a full version of this As2Doc program, it's friggin awesome, I'm addicted to it!

_Michael

zwetan
March 3rd, 2006, 07:12 AM
hi, just stumb on those posts by hazard

some time ago a I released the core2 library (http://www.burrrn.com/projects/core2.html) which implement some part of the .NET core class in AS1, AS2 etc.

and off course String.format method (http://www.burrrn.com/documentation/core2/files/buRRRn/core2/String-es.html#String.format)

for a number formater the toExponential, toFixed, toPrecision methods should help ;).

MichaelxxOA
March 3rd, 2006, 12:57 PM
Udpated with a new method added, replace... and documentation...

www.nowtheworld.com/asdocs/stringutility

the new code listing is found in the first post. Take Care.

_Michael