Question

I am new to RegExp, I tried creating a RegExp in Flex AS3, that matches anything not in pattern given in my expression my_regex. That is, I want to match everything excluding "^():,?+*/." (without double quotes). But my program behaves very weird, it shows error string on alternate characters typing. Please suggest what is wrong with my regexp.

`

<fx:Script>
    <![CDATA[
        private const my_regex:RegExp = /\b[^():,?+*\.]/g;

        private function validateNow(evt:Event):void {
            if (my_regex.test(ti.text)) {
                ti.errorString = null;
            } else {
                ti.errorString = "some error here";
            }
        }
    ]]>
</fx:Script>

<mx:TextInput id="ti" change="validateNow(event)"/>

`

Was it helpful?

Solution 2

A few issues with your regex...

First, you need to escape many of those characters, as they have special meanings in regex. You can escape their special function (thereby referring only to the character) by preceding each with a backslash. Honestly, you can get away with escaping them all.

EDIT: \b does indeed mark a word boundary in most contexts, however, it is extraneous to our purposes here.

Your revised regex is...

private const my_regex:RegExp = /[\^\(\)\:\,\?\+\*\\\.]/g;

The other consideration is that, if you run my_regex.test(ti.text), if any of these characters appear in the string, it will return true. In order for your error string to have a value when there is a match, you have to reverse your logic. I did with the not (!) operator before the call to .test.

private function validateNow(evt:Event):void {
    if (!my_regex.test(ti.text)) {
       ti.errorString = null;
    } else {
       ti.errorString = "some error here";
    }
}

I highly recommend having a reference on regular expressions handy. My personal favorite is The ActionScript 3.0 Bible 2e. Chapter 12 goes into exhaustive detail. If you prefer web resources, the AS3 documentation works nicely.

OTHER TIPS

Your if logic seems to be reversed.

Get rid of \b because it represents a "word boundary" (not needed here).

The ^ at the beginning of the character class (the content inside the square brackets) negates it. The ^ at any other position of the character class represents that literal character (that is why I've added one at the end).

If you use var ti:TextInput = evt.target as TextInput; in your method, you will be able to apply that method to several different TextInputs (and why do you use the old mx component, better use spark).

Here is my solution (the second TextInput is red, because spaces are not allowed by the regex):

screenshot

Here the code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[
            private const my_regex:RegExp = /[^():,?+*\.^]/;

            private function handleChange(evt:Event):void {
                var ti:TextInput = evt.target as TextInput;

                trace("text=" + ti.text);
                trace("test=" + my_regex.test(ti.text) + "\n");

                if (my_regex.test(ti.text)) {
                    ti.errorString = 'Only these chars are allowed: ():,?+*.^';
                } else {
                    ti.errorString = null;
                }
            }
        ]]>
    </fx:Script>

    <s:TextInput id="ti1" change="handleChange(event)"
        horizontalCenter="0" top="50"/>

    <s:TextInput id="ti2" change="handleChange(event)"
        horizontalCenter="0" top="100"/>

    <s:TextInput id="ti3" change="handleChange(event)"
        horizontalCenter="0" top="150"/>
</s:Application>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top