0

See, in my Ruby on Rails application, Regex expression is being used for Validation done using jQuery Validation Engine. So, I need a regex for a custom requirement,

My requirement:

  1. It should contain only alphabets, numbers, special characters #, _, -, (, ), ., * and whitespace.

  2. It should start with an alphabet or number, or special characters # OR *

  3. It should end with an alphabet or number, or special characters . OR )

  4. It should not allow consecutive special characters

  5. It should check that for any starting parentheses '(', there is a closing parentheses ')'

  6. It should limit the whole character length to 25

I have tried the below expression in rubular.com:

/^([a-zA-Z]|\d|\#|\*)(([a-zA-Z]*\d*\(?\)?\-?\.?)*)([a-zA-Z]|\d|\)|\.)$/

But, for the above expression,

It will allow combinations like '*)', '()','*.' etc. It should have at least a character or number between the special characters. Also, now it will not check for starting parentheses '(' even though we enter ')'. So, these are the issues.

Can anyone just help me out.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
Rajesh Omanakuttan
  • 6,788
  • 7
  • 47
  • 85
  • 1
    @sawa: "?<>',?[]}{=-)(*&^%$#`~{}" these are the special characters and I have given what all sp. characters I would like to allow. Hope it is clear for you. – Rajesh Omanakuttan Apr 02 '14 at 04:26
  • 1
    What do you mean, "there are issues"? What *specifically* doesn't work? Can you give counterexamples that pass where they shouldn't, or fail where they should be correct? Without it, it's a lazy question, dumping a lot of the work onto other people. You should make your questions as easy to understand and answer as possible. See here: http://stackoverflow.com/help/how-to-ask – Amadan Apr 02 '14 at 05:20
  • @Amadan: I've explained the issues. Pls check – Rajesh Omanakuttan Apr 02 '14 at 05:29
  • 1
    Are multiple tests and regex posible? This problem is much easier if you don't try and squeeze all the requirements into one single complex regex. For instance, `/\A.{1,25}\z/` applies the length restriction, but nothing else. – Neil Slater Apr 02 '14 at 06:45
  • @NeilSlater: That means I need to sepearte it and do it one by one. right? Yes, that would be the best solutions available. Thanks Neil. – Rajesh Omanakuttan Apr 02 '14 at 06:51
  • 1
    @RajeshCO: I think you can combine items 1..3 easily enough, but the remainder are much simpler stand-alone. – Neil Slater Apr 02 '14 at 06:53
  • @NeilSlater: I'm not that proficient in Regex handling. Can you just help me by putting an answer for it. Thank you. – Rajesh Omanakuttan Apr 02 '14 at 07:08

1 Answers1

1

It may be possible to encode all the rules into a single regular expression, but the rules for starting characters, consecutive characters, paired brackets and overall length would combine to make a very hard-to-code and hard-to-read regular expression (the overall complexity of your requirements is approaching the need for a grammar-based solution - e.g. a parser).

I suggest coding multiple validation tests, some of which are regex based, and testing them in sequence.

You can start with your items 1..3 (characters allowed in start, middle, end of string), which your current solution is very close to. I'd prefer just character classes here, note this regex assumes string is always at least 2 characters, in addition to your listed rules:

/\A[a-zA-Z0-9\#\*][a-zA-Z0-9\#\*\.\(\)\s\-_]*[a-zA-Z0-9\.\)]\z/

NB I prefer \A for start of string and \z for end, but ^ and $ are probably just fine for your use.

The following regex will find consecutive special characters (your rule 4), so you must negate it (test using !~ instead of =~)

/[\#\*\.\(\)\s\-_]{2}/

Checking for paired brackets (rule 5) is hard using regex. Instead you should check for any opening or closing bracket /[\(\)]/, and if there are any at all, check that they pair up with some more code. See this answer to a similar requirement which gives an algorithm.

Finally, for checking the length (rule 6) you don't even need regular expressions. If your input is in str, then str.size <= 25 would be enough.

Community
  • 1
  • 1
Neil Slater
  • 26,512
  • 6
  • 76
  • 94