RegExp in Flash 8 using ExternalInterface

After posting about the new ExternalInterface class in Flash 8, there was a comment suggesting the use of it to get Regular Expression functionality into Flash. Well, I thought that was a fine idea, and it turns out it’s pretty easy to implement.

I’ve already covered some of the uses of ExternalInterface in this other blog post. It focuses on sending values from an HTML page into the Flash movie. That’s only half of what makes ExternalInterface so cool. Another way to use it is to call a Javascript function in your HTML page from your Flash movie and have it return a value.

If you want to jump right in, here’s my RegEx in Flash example page.

For this example I added two methods to the String class: String.match and String.replace. I used the prototype object because it’s the quickest way to add it in. Here’s the code in Flash:

// add match to String
String.prototype.match = function(reg) {
   var arr = ExternalInterface.call("reMatch", escape(this.toString()), escape(reg));
   for (var i=0;i<arr.length;i++) {
      arr[i] = unescape(arr[i]);
   }
   return arr;
}
// add replace to String 
String.prototype.replace = function(reg, rep) {
	return ExternalInterface.call("reReplace", escape(this.toString()), escape(reg), escape(rep));
}

As you can see, the code is very simple. When using ExternalInterface.call, the first argument is the name of the function you want to call in your HTML document, and the rest are arguments you want to pass in to it. The Flash player takes those values, passes them to your Javascript function and sends the result back in real time.

In my HTML document, I added two functions to handle the RegExp calls and return the values:

// RegEx replace
function reReplace(str, reg, rep) {
   var s = unescape(str);
   var re = new RegExp(eval(unescape(reg)));
   return s.replace(re, unescape(rep));
}
// RegEx match
function reMatch(str, reg) {
   var s = unescape(str);
   return s.match(eval(unescape(reg)));
}

// escape the values in the array because 
// ExternalInterface doesn't escape some properly
function encodeArray(arr) {
   for (var i=0; i<arr.length;i++) {
      arr[i] = escape(arr[i]);
   }
   return arr;
}

There’s a few more lines added in that test for the existence of ExternalInterface by checking the ExternalInterface.available variable. If that returns false, I redirect the user to an upgrade message inside the swf file.

For most people this would be plenty of support for RegExp, but if you wanted even more control, it should be fairly easy to write an entire RegExp class that uses ExternalInterface and some Javascript functions to get full Regular Expression support into Flash.

Here’s a link to the example page again:
RegExp in Flash 8 using ExternalInterface.

UPDATE: Just wanted to add a link to a little RegExp class I found via Google. Looks like a nice alternative if you don’t mind the 20k file size.

UPDATE (2-24-2005): Updated this code to fix a couple bugs with non-escaped chars. This all works except when trying to match spaces. It looks like the Flash player has issues encoding spaces when using ExternalInterface. If you try to match something like /s/g, you’ll get an array of ‘null’s back. I’ve also recreated the original fla file and zipped it up for download.

UPDATE: I went ahead and added a few more lines to the code so all the characters are properly escaped. Every regex you throw at it should work now.

18 thoughts on “RegExp in Flash 8 using ExternalInterface

  1. Really nice :)
    Did you test/know the number of character max that we can send by ExternalInterface ?

  2. Great example! Flash 8.5 player will supposedly support regex with the AS3.0 release! yippie!

  3. I recently found a major bug in ExternalInterface. If the value you pass from JavaScript contains a newline, Flash corrupts the value. For example, if you had the following value:

    helloworld1
    helloworld2
    helloworld3

    And passed this from JavaScript to Flash (perhaps you got it from the user in an HTML textarea, and are passing it over to Flash), Flash will corrupt the value and turn it into a random number, which looks like some kind of internal memory pointer. I’ve found this on all browsers on all platforms I have tested (Mac and Windows, on IE, Firefox, and Safar).

    This bug is preventing me from using ExternalInterface for now.

  4. Have you tried using encode() or encodeURIComponent() to encode the text before sending it over? Then you can use unescape or something to unencode it inside Flash.

  5. This is a very usefull technic.
    BTW, there is a problem when using reserved regexp patterns like \s from the compiled swf.
    The compiler analyse the backslash as an escaped character, and it doesn’t exists in actionscript tongue.
    So that produce an error.

    The only trick I’ve found is to escape the reserved pattern.
    For example, to search any spaces in a string from the swf you’d call :
    result:String = myRegExp.search (“/\s/g”, “replaced”);

    I think that in more difficult patterns, that can be a problem.
    Imagine yyou want to search a / in the string, do you have to triple escape the pattern ?
    result:String = myRegExp.search (“/////g”, “replaced”);

    Any thought ?

  6. This is a very usefull technic.
    BTW, there is a problem when using reserved regexp patterns like s from the compiled swf.
    The compiler analyse the backslash as an escaped character, and it doesn’t exists in actionscript tongue.
    So that produce an error.

    The only trick I’ve found is to escape the reserved pattern.
    For example, to search any spaces in a string from the swf you’d call :
    result:String = myRegExp.search (“/\s/g”, “replaced”);

    I think that in more difficult patterns, that can be a problem.
    Imagine yyou want to search a / in the string, do you have to triple escape the pattern ?
    result:String = myRegExp.search (“/////g”, “replaced”);

    Any thought ?

    Great resource. Really helpful for understand odbc things.

    Thanks.

  7. This is great article indeed.

    For whose of you who may require more complex expressions (esp in terms of replacements) I’d like to make a sample note I’ve used for generating email links within a textarea:
    regex

    /([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+/g

    replace pattern (replaces the email with an address itself)

    <a href='mailto:$0' target='_blank'>$0</a>

  8. Well what can I say, Your a god damn genius – Okay maybe thats a bit over the top :)
    Already a big fan of the swfobject getting my multitude of emails a day. Why these people have to ask you te unsubscibe i just dont’t know. You think they would be savvy enough to be able to do it themsleves???. Anyway searching the net for a regexp to get rid of a forward slash “/” and who’s site should google pop up but yours. Great example as I am not the king of regexp and this did exactly what it said on the tin. How you have time to do your blog, swfobject and hold down a job i just don’t know. Just keep doing it though as I am finding it really helpful at the mo. Cheers Dude.

  9. The following is what I currently use in projects for validating email. I use AS2/F8 and ExternalInterface, and it works wonderfully. Remember that ExternalInterface is synchronous, so that you can do the following.

    var isValid = Boolean(flash.external.ExternalInterface.call("validate", emailTextInput.text));

    Place this javascript in your “<head>” tag.

    <script type="text/javascript">
    function validate(email) {
    var s = unescape(email);
    var re = /^w+([.-]?w+)*@w+([.-]?w+)*(.w{2,3})+$/
    if(re.test(s)) {
    alert("Valid Email");
    return true;
    }
    return false;
    </script>

    Remember to have the following line in your “<object><param name=”allowScriptAccess” value=”always” />

    As well as having the same attribute in your “<embed>” tag.

    <embed allowScriptAccess="always" />

Comments are closed.