tags:

views:

418

answers:

3

I'm not exactly a regex guru, so I have some difficulty finding a regular expression for the following case.

I'd like to match a string of the form <prefix>$rolename$<suffix> (e.g. abc$rolename$def) that has a maximum length of 20. Both <prefix> and <suffix> can be empty and may contain any character. The $rolename$ part is required.

Shouldn't be difficult but I just can't figure out how to do this. Can anyone help me?

+1  A: 

The regular expression I'd use would be /^([^\$]*)\$rolename\$([^\$]*)$/, validating the total length of the string externally.

Joaquim Rendeiro
Sounds right. I'm not sure you need to escape dollars in character groups - `[^$]` might do. I'll add that you want to test the length first, before the regex. It is much cheaper.
Kobi
In my case it is impossible to validate the string length externally. I'd like to validate an input field in a user interface. The input field and its validation code (regex validation) are generated. I can not change the generation of this code.
Ronald Wildenberg
@rwwilden - I've added an option for you, but it's ugly. It's odd that you're allowed to control a regex validation, but not maximum length. This is very common for text boxes...
Kobi
A: 

why regex? think simple. depending on your language, check for length using your language's string length methods eg using Python

if len(mystring) <= 20:
     if "$rolename" in mystring:
         print "ok"

your language may have similar methods like index() to find where a substring is in a string.

I really need a regex. If the problem was this simple to solve, I wouldn't have asked :) See also my comment for the answer by Joachim Rendeiro.
Ronald Wildenberg
then you should have stated this when you post our question.
+4  A: 

Since you have to use a regex, as you've explained, here's an option:

^(?!.{21,})(.*?)\$rolename\$(.*?)$

This is similar to Joachim's answer, but with a negative lookahead at the beginning. That is: before the regex is matched, we check the string does not have 21 or more characters.

Kobi
That's exactly what I want, thanks. I was just wondering why you have (.*?) instead of (.*) around $rolename$.
Ronald Wildenberg
This is a non-greedy capture. I hadn't tested performances, but it should be a little better. It's supposed to stop when it finds `$rolename$`, instead of keep going until the end, failing and back-tracking.
Kobi
Come to think of it, `(?!.{21})` would work just the same, and also `(?=.{1,20}$)` if you're an optimist :)
Kobi