.NET Framework - Regex - Ensure 0,1 occurrences from a list of possibilities

Asked By Byro on 27-Mar-09 12:57 PM
I'm looking for an expression that checks that within a string only certain
characters appear, and that they appear at most 1 time.  For example, a
string can have up to 4 unique digits between 1 and 4.

The following strings should pass:
D-1
D-14
D-1234
D-41

The following should fail:
D-  (no digit)
D-0 (out of range)
D-5 (out of range)
D-11 (repeated digit)
D-1 2 (embedded space)
D-12345 (out of range and too long)

The expression "D-[1234]{1,4}" comes close, but it matches even when a digit
is repeated within the string.

Any help would be greatly appreciated.




Peter Duniho replied on 27-Mar-09 01:39 PM
On Fri, 27 Mar 2009 09:57:04 -0700, Byron


I'm no regex expert.  But, I suspect you can use the conditional
expression syntax to accomplish what you want.

That said, that doesn't mean regex is the best solution.  Sometimes,
simply writing some code is a better way to express what you're doing.  I
think that using the conditional syntax, a suitable regex expression would
be, while more concise than the equivalent C#, also very difficult to
easily infer its purpose, as well as to modify should the requirements
change later.

Pete
nospa replied on 29-Mar-09 06:17 AM
i am not a regex expert, so there is probably a better way, but this
works

Regex tester = new Regex(@"D-(" +
@"(?<m1>[1234])|" +
@"(?<m1>[1234])(?<m2>(?!\k<m1>)[1234])|" +

@"(?<m1>[1234])(?<m2>(?!\k<m1>)[1234])(?<m3>(?!(\k<m1>|\k<m2>))[1234])|"
+

@"(?<m1>[1234])(?<m2>(?!\k<m1>)[1234])(?<m3>(?!(\k<m1>|\k<m2>))[1234])"
+
@"(?<m4>(?!(\k<m1>|\k<m2>|\k<m3>))[1234])" +
@")$");
invegat

On Fri, 27 Mar 2009 09:57:04 -0700, Byron
Jesse Houwing replied on 02-Apr-09 05:17 AM
Hello Byron,


As there's only a few possibilities, you could write them out like this:

(1234|1324|1342|1423|1432|....4321)

And do the same with the other options.

A better wat woukd be to check the general format with a regex, and then
later (if you're using asp.net validators) check the other requirement.

There are other possibilities (as invegat pointed out), but those aren't
supported by clientside Javascript , which would require a serverside check
anyway.

--
Jesse Houwing
jesse.houwing at sogeti.nl
nospa replied on 29-Mar-09 08:07 PM
By my calculation there are 504 possibilities, I would not call that
matching strings with a 1 time use program.
Mark Tolonen replied on 29-Mar-09 09:16 PM
There are 64 possibilities:
Mark Tolonen replied on 29-Mar-09 09:30 PM
There are only 64 permutations.  Not a pretty regex though:

3124|3142|3214|3241|3412|3421|4123|4132|4213|4231|4312|4321|123|
124|132|134|142|143|213|214|231|234|241|243|312|314|321|324|341|342|
412|413|421|423|431|432|12|13|14|21|23|24|31|32|34|41|42|43|1|2|3|4)$"

-Mark
nospa replied on 30-Mar-09 02:26 AM
You are right, 64.   With that number your way is probably at least
100 times faster.
Jeff Johnson replied on 30-Mar-09 01:51 PM
Maybe there's a Regex guru out there who can help you, but my personal
advice is that you should put down your Regex hammer and stop looking for
nails to hit with it. Parse these strings with plain old boring code and
move on.