6

Using Actionscript 3.0 (Within Flash CS5)

A standard regex to match any digit is:

var myRegexPattern:Regex = /\d/g;

What would the regex look like to incorporate a string variable to match? (this example is an 'IDEAL' not a 'WORKING' snippet) ie:

var myString:String = "MatchThisText"
var myRegexPatter_WithString:Regex = /\d[myString]/g;

I've seen some workarounds which involve creating multiple regex instances, then combine them by source, with the variable in question, which seems wrong. OR using the flash string to regex creator, but it's just plain sloppy with all the double and triple escape sequences required.

There must be some pain free way that I can't find in the live docs or on google. Does AS3 hold this functionality even? If not, it really should.

Or I am missing a much easier means of simply avoiding this task that I'm simply naive too due to my newness to regex?

Adrian Seeley
  • 2,262
  • 2
  • 29
  • 37
  • 4
    I suppose `new RegExp("\\d" + myString, "g")` is what you want to avoid? I don't think there's another way, but I would be interested if there were. – RIAstar Jul 11 '11 at 22:08
  • In Perl you could do it with `/\d$myString/g`, but that's Perl. ;) – Qtax Jul 11 '11 at 22:20
  • @RIAstar: I was just about to write that as an answer. – shanethehat Jul 11 '11 at 22:22
  • @shanethehat: Sorry 'bout that. I always feel like a one-line answer isn't good enough. Anyway @Tyler had a better one. – RIAstar Jul 11 '11 at 22:30

2 Answers2

9

I've actually blogged about this, so I'll just point you there: http://tyleregeto.com/using-vars-in-regular-expressions-as3 It talks about the possible solutions, but there is no ideal one like you mention.

EDIT

Here is a copy of the important parts of that blog entry:

Here is a regex to strip the tags from a block of text.

/<("[^"]*"|'[^']*'|[^'">])*>/ig

This nifty expression works like a charm. But I wanted to update it so the developer could limit which tags it stripped to those specified in a array. Pretty straight forward stuff, to use a variable value in a regex you first need to build it as a string and then convert it. Something like the following:

var exp:String = 'start-exp' + someVar + 'more-exp';
var regex:Regexp = new RegExp(exp);

Pretty straight forward. So when approaching this small upgrade, that's what I did. Of course one big problem was pretty clear.

var exp:String = '/<' + tag + '("[^"]*"|'[^']*'|[^'">])*>/';

Guess what, invalid string! Better escape those quotes in the string. Whoops, that will break the regex! I was stumped. So I opened up the language reference to see what I could find. The "source" parameter, (which I've never used before,) caught my eye. It returns a String described as "the pattern portion of the regular expression." It did the trick perfectly. Here is the solution:

var start:Regexp = /])*>/ig;
var complete:RegExp = new RegExp(start.source + tag + end.source);

You can reduce it down to this for convenience:

var complete:RegExp = new RegExp(/])*>/.source + tag, 'ig');
Tyler Egeto
  • 5,505
  • 3
  • 21
  • 29
  • _"Better escape those quotes in the string. Whoops, that will break the regex!"_ I don't think so. If you escape the quotes in the string, these escapes are removed when the string is interpreted and the regex constructor never sees them. – ridgerunner Jul 12 '11 at 01:11
  • Ahh thats beautiful! SO mine would look something like :: new RegExp(/\d/.source + myString, g); – Adrian Seeley Jul 12 '11 at 02:25
  • 1
    +1 for the `source` property also. But your examples are kinda confusing. I'm not sure I follow you when you write `end.source` while I see that your `start` looks very much like what the end should be. I'm also not so strong on RegEx so maybe a small clarification there would help out. Good post! – GV3 Jul 24 '13 at 06:57
6

As Tyler correctly points out (and his answer works just fine), you can assemble your regex as a string end then pass this string to the RegExp constructor with the new RegExp("pattern", "flags") syntax.

function assembleRegex(myString) {
    var re = new RegExp('\\d' + myString, "i");
    return re;
}

Note that when using a string to store a regex pattern, you do need to add some extra backslashes to get it to work right (e.g. to get a \d in the regex, you need to specify \\d in the string). Note also that the string pattern does not use the forward slash delimiters. In other words, the following two statements are equivalent:

var re1 = /\d/ig;
var re2 = new Regexp("\\d", "ig");

Additional note: You may need to process the myString variable to escape any backslashes it might contain (if they are to be interpreted as literal). If this is the case the function becomes:

function assembleRegex(myString) {
    myString = myString.replace(/\\/, '\\\\');
    var re = new RegExp('\\d' + myString);
    return re;
}
ridgerunner
  • 33,777
  • 5
  • 57
  • 69
  • @Adrian Seeley: You're going to have to escape backslashes in the variable no matter which solution you choose (and you're going to have to use `new RegExp()`). But as I've shown above, its no big deal - just a single statement. So I guess the _real_ answer to your question is NO. (And BTW the `RegExp` constructor is a core JavaScript feature, and is not AS3/Flash specific.) – ridgerunner Jul 12 '11 at 02:44
  • +1 a valid solution, but all the extra escapes does tend to make things more confusing, in my opinion, and I find regexp's confusing enough as it is, especially when you return a few months later. – Tyler Egeto Jul 12 '11 at 02:46