Adverti horiz upsell
MEL Scripting: Tokenize Command
MEL Scripting: Tokenize Command
Jay Grenier 12,728 views  Rating:
(2 ratings)
Page 1 of 1

The original tutorial can be found here: https://www.scriptswell.net/2010/03/mel-tutorial-tokenize.html

The tokenize MEL command is incredibly useful and very easy to use. You'll find once you know how it works and what it does, you'll end up using it in almost every script you write in one way or another. What tokenize does is essentially break a string up into different parts based on a splitter character, and return them into an empty string array. Why would you need to break up a string into different parts? There are many reasons you may need to do this. An example being let's say you're string is an Object.Attr and you need to parse out just the attribute, or perhaps just the object. You can use tokenize to split them up into their own strings. Maybe you have a path to a file and you want to tokenize it by slashes. Or, you have a comma-separated line of text and you want to split each field into an array. There are countless ways to use it and I think you'll find once you know how to use it, you'll use it constantly. Let's look at some examples:

"myObject.translateX" would tokenize into "myObject" and "translateX". Here's how we would do that:

  1. // Here is our string, in the variable $myString  
  2. string $myString = "myObject.translateX" ;  
  3.   
  4. // First we create an empty string array, to play our "parts" in.  
  5. string $buffer[] ;  
  6.   
  7. // Now we'll tokenize our string and put the tokens into $buffer  
  8. tokenize $myString "." $buffer ;  
  9.   
  10. // Notice the arguments:  string, splitter, array.  
  11.   
  12. // Now if we print out $buffer we'll get:  
  13. print $buffer ;  
  14. // Result:  
  15. // myObject  
  16. // translateX  

    // Here is our string, in the variable $myString
    string $myString = "myObject.translateX" ;

    // First we create an empty string array, to play our "parts" in.
    string $buffer[] ;

    // Now we'll tokenize our string and put the tokens into $buffer
    tokenize $myString "." $buffer ;

    // Notice the arguments: string, splitter, array.

    // Now if we print out $buffer we'll get:
    print $buffer ;
    // Result:
    // myObject
    // translateX

    Note: Because we used the "." as the splitter, it is now gone from any return strings.

    Besides just splitting a string up into different parts, tokenize will also return the number of parts your string was split up into. This can be useful for many reasons as well. Let's say you have a string that looks like this: "myObject,myAttribute,myValue,myMultiplier,myComment". This could be a comma-separated text file you're reading from, or data from a database table. So now for whatever reason let's say we want to know how many comma-separated fields are in this line of text. We can use tokenize for that as well.

    1. // This is the original string  
    2. string $myLine = "myObject,myAttribute,myValue,myMultiplier,myComment" ;  
    3.   
    4. // Tokenize it, but save the return of tokenize into an INT variable  
    5. string $buffer[] ;  
    6. int $numTokens = `tokenize $myLine "," $buffer` ;  
    7.   
    8. print $numTokens ;  
    9. // Result: 5  
    10.   
    11. print $buffer ;  
    12. // Result:  
    13. // myObject  
    14. // myAttribute  
    15. // myValue  
    16. // myMultiplier  
    17. // myComment  

    // This is the original string
    string $myLine = "myObject,myAttribute,myValue,myMultiplier,myComment" ;

    // Tokenize it, but save the return of tokenize into an INT variable
    string $buffer[] ;
    int $numTokens = `tokenize $myLine "," $buffer` ;

    print $numTokens ;
    // Result: 5

    print $buffer ;
    // Result:
    // myObject
    // myAttribute
    // myValue
    // myMultiplier
    // myComment

    Now we have both our tokens saved into $buffer and the number of tokens saved into $numTokens. Now that you've got your 5 fields into your $buffer array, you can now define them properly.

    1. // Define Vars  
    2. string $object = $buffer[0] ;  
    3. string $attribute = $buffer[1] ;  
    4. string $value = $buffer[2] ;  
    5. string $multiplier = $buffer[3] ;  
    6. string $comment = $buffer[4] ;  

    // Define Vars
    string $object = $buffer[0] ;
    string $attribute = $buffer[1] ;
    string $value = $buffer[2] ;
    string $multiplier = $buffer[3] ;
    string $comment = $buffer[4] ;

    Note: Remember MEL arrays are "zero-based" so the first index of $buffer is going to be zero.

    You may notice that I've defined $value and $multiplier as strings in the above example. Since they are coming from a comma-separated string and then tokenized into a string array they are technically strings. However, since they are most likely floats I can define them as such when I take them out of $buffer. You will get a Warning in Maya when you do this, but it won't stop your script. Same example but with redefined vars below:

    1. // Define Vars, But Assign To Float  
    2. string $object = $buffer[0] ;  
    3. string $attribute = $buffer[1] ;  
    4. float $value = $buffer[2] ;  
    5. float $multiplier = $buffer[3] ;  
    6. string $comment = $buffer[4] ;  

    // Define Vars, But Assign To Float
    string $object = $buffer[0] ;
    string $attribute = $buffer[1] ;
    float $value = $buffer[2] ;
    float $multiplier = $buffer[3] ;
    string $comment = $buffer[4] ;

    Now we've got five values that we took from our comma-separated text line, all in their own variables with no commas. Very useful! Now, what if we need to save this data out again? How do you form a line again with all these variables? The practical way would be to do this:

    1. // Redefine CSV String  
    2. string $myNewLine = ($object+","+$attribute+","+$value+","+$multiplier+","+$comment) ;  

    // Redefine CSV String
    string $myNewLine = ($object+","+$attribute+","+$value+","+$multiplier+","+$comment) ;

    This will put all your variables into a new, single string variable. But, if you've done this sort of thing you may have noticed that this will produce an error in MEL, because we're attempting to concatenate two different types of variables a string. In MEL, we can't combine floats and strings together into a string. (Thank you Python!) So, the alternative is to just use our original string array from your tokenize, along with the MEL command: stringArrayToString.

    1. // Redefine CSV String  
    2. string $newLine = stringArrayToString($buffer, ",") ;  

    // Redefine CSV String
    string $newLine = stringArrayToString($buffer, ",") ;

    That will reassemble our string array into a single line again, and use the comma as the splitter. You can use anything you want as a splitter as long as it's a valid character.

    Play around with tokenize a bit and see what you can come up with. It's one of the MEL commands I use the most and getting comfortable with how it works and how to use it will improve your scripting a lot!

    For more MEL scripting tutorials and information please visit: https://www.scriptswell.net