Saif Ahsanullah
Saif Ahsanullah

Reputation: 204

regex expression help needed

I was wondering if this was possible using Regex. I would like to exclude all letters (upper and lowercase) and the following 14 characters ! “ & ‘ * + , : ; < = > @ _

The problem is the equal sign. In the string (which must either be 20 or 37 characters long) that I will be validating, that equal sign must either be in the 17th or 20th position because it is used as a separator in those positions. So it must check if that equal sign is anywhere other than in the 16th or 20th position (but not both). The following are some examples:

pass: 1234567890123456=12345678901234567890

pass: 1234567890123456789=12345678901234567

don't pass: 123456=890123456=12345678901234567

don't pass: 1234567890123456=12=45678901234567890

I am having a hard time with the part that I must allow the equal sign in those two positions and not sure if that's possible with Regex. Adding an if-statement would require substantial code change and regression testing because this function that stores this regex currently is used by many different plug-ins.

Upvotes: 1

Views: 105

Answers (2)

Andrey Ershov
Andrey Ershov

Reputation: 1803

I've omitted other symbols matching other symbols and just placed the [^=], you should have there code for all allowed symbols except =

var r = new Regex(@"^(([0-9\:\<\>]{16,16}=(([0-9\:\<\>]{20})|([0-9\:\<\>]{3})))|(^[^=]{19,19}=(([0-9\:\<\>]{17}))?))$");
/*
    @"^(

    ([0-9\:\<\>]{16,16}
    =
    (([0-9\:\<\>]{20})|([0-9\:\<\>]{3})))

    |

    (^[^=]{19,19}
    =
    (([0-9\:\<\>]{17}))?)

    )$"
*/

using {length,length} you can also specify the overall string length. The $ in the end and ^ in the beginning are important also.

Upvotes: 1

kipy
kipy

Reputation: 632

I'll go for

^([^a-zA-Z!"&'*+,:;<=>@_]{16}=[^a-zA-Z!"&'*+,:;<=>@_]+|[^a-zA-Z!"&'*+,:;<=>@_]{19}=[^a-zA-Z!"&'*+,:;<=>@_]*)$

Explanations :

1) Start with your allowed char :

^[^a-zA-Z!"&'*+,:;<=>@_]$

[^xxx] means all except xxx, where a-z is lower case letters A-Z upper case ones, and your others chars

2) Repeat it 16 times, then =, then others allowed chars ("allowed char" followed by '+' to tell that is repeated 1 to n times)

^[^a-zA-Z!"&'*+,:;<=>@_]{16}=[^a-zA-Z!"&'*+,:;<=>@_]+$

At this point you'll match your first case, when = is at position 17.

3) Your second case will be

^[^a-zA-Z!"&'*+,:;<=>@_]{19}=[^a-zA-Z!"&'*+,:;<=>@_]*$

with the last part followed by * instead of + to handle strings that are only 20 chars long and that ends with =

4) just use the (case1|case2) to handle both

^([^a-zA-Z!"&'*+,:;<=>@_]{16}=[^a-zA-Z!"&'*+,:;<=>@_]+|[^a-zA-Z!"&'*+,:;<=>@_]{19}=[^a-zA-Z!"&'*+,:;<=>@_]*)$

Tested OK with notepad++ and your examples


Edit to match exactly 20 or 37 chars

^([^a-zA-Z!"&'*+,:;<=>@_]{16}=[^a-zA-Z!"&'*+,:;<=>@_]{3}|[^a-zA-Z!"&'*+,:;<=>@_]{16}=[^a-zA-Z!"&'*+,:;<=>@_]{20}|[^a-zA-Z!"&'*+,:;<=>@_]{19}=|[^a-zA-Z!"&'*+,:;<=>@_]{19}=[^a-zA-Z!"&'*+,:;<=>@_]{17})$

More readable view with explanation :

`
^(                              
                                // 20 chars with = at 17
    [^a-zA-Z!"&'*+,:;<=>@_]{16} // 16 allowed chars
    =                           // followed by =
    [^a-zA-Z!"&'*+,:;<=>@_]{3}  // folowed by 3 allowed chars
|                               
    [^a-zA-Z!"&'*+,:;<=>@_]{16} // 37 chars with = at 17   
    =                           
    [^a-zA-Z!"&'*+,:;<=>@_]{20}
|
    [^a-zA-Z!"&'*+,:;<=>@_]{19} // 20 chars with = at 20   
    =
|
    [^a-zA-Z!"&'*+,:;<=>@_]{19} // 37 chars with = at 20
    =
    [^a-zA-Z!"&'*+,:;<=>@_]{17}
)$

`

Upvotes: 2

Related Questions