1

I am doing a regexp validation for email. works fine but it allows the user to add the @.xyz.com, but it is meaning less. how can i insure that, the user should only add the alphabet next to @ symbol?

in the pattern i have added [\w\.] for the reason to add after @ is @some.xx.com purpose. ( user can enter . after/inside alphabet )

$(function(){
 
 $('#email').on('keyup', function(event){
   
   var email = event.target.value;
   var pattern = /^([a-zA-Z]{3,})+@[\w\.]+\.(com|org)$/
   if(!email) return false;
   
   console.log(pattern.test(email));
   
 })
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="email" id="email" value="" />

any one help me?

CinCout
  • 9,486
  • 12
  • 49
  • 67
3gwebtrain
  • 14,640
  • 25
  • 121
  • 247

2 Answers2

3

Because what follows the @ must be a word character, just add a word boundary after the @ with \b. Also note that . does not need to be escaped in a character set, and you can use the i (case insensitive) flag so as not to have to repeat [a-zA-Z]:

$('#email').on('keyup', function(event) {
  var email = event.target.value;
  var pattern = /^([a-z]{3,})+@\b[\w.]+\.(?:com|org)$/i
  if (!email) return false;

  console.log(pattern.test(email));

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="email" id="email" value="" />

If you additionally want to make sure that .s in the input aren't right next to each other, then repeat (?:\w+\.) instead of the character set:

$('#email').on('keyup', function(event) {
  var email = event.target.value;
  var pattern = /^([a-z]{3,})+@(?:\w+\.)+(?:com|org)$/i
  if (!email) return false;

  console.log(pattern.test(email));

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="email" id="email" value="" />
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • why do you add `?:` mark inside the `or` operator?, even without it works – 3gwebtrain Dec 24 '18 at 05:07
  • Capturing groups should be used for when you need to use the captured group later - such as when trying to match only part of a string, or when you want to be able to backreference the group later in the pattern. If one isn't doing that, best to use a non-capturing group instead, with `(?:` rather than `(`, (could do the same with the initial group, though I'm not sure of its purpose, you might just remove that group entirely) – CertainPerformance Dec 24 '18 at 05:08
  • How could you manage this @CertainPerformance? Just outstanding! – Prashant Pimpale Dec 24 '18 at 05:11
  • This will produce a false positive for strings like `'aaa@a..xyz.com'` – ic3b3rg Dec 24 '18 at 05:11
  • 1
    @3gwebtrain eg if I'm reading code and I see a pattern with a group `(`, that makes me think "This group is being captured, I need to keep in mind that it may be used later", whereas `(?:` instead would make it clear that the group only exists to enable alternation inside it (or to repeat the pattern inside, etc) - it makes the pattern easier to read, the intent is clearer. – CertainPerformance Dec 24 '18 at 05:12
  • capturing groups in a test regex are irrelevant – ic3b3rg Dec 24 '18 at 05:15
  • @ic3b3rg If you're reading some code and you're 100% sure in advance that a pattern is going to be used for `.test` and nothing else, sure - but that's often not the case, and I think there are benefits a consistent style with the least cognitive overhead. – CertainPerformance Dec 24 '18 at 05:19
  • @CertainPerformance the use case here is clearly for validation - the non-capturing groups only add unnecessary complexity – ic3b3rg Dec 24 '18 at 05:22
  • Sounds like you're not ready to embrace "least cognitive overhead" ;) – ic3b3rg Dec 24 '18 at 05:32
0

You're looking for repeating patterns of \w+\. after the @, i.e.

const tests = [
  'aaa@.xyz.com',
  'aaa@a.xyz.com',
  'aaa@a..xyz.com',
  'aaa@some.xx.com'
]

tests.forEach(test => {
  console.log(test, /^([a-z]{3,})+@(\w+\.)+(com|org)$/i.test(test));
});
ic3b3rg
  • 14,629
  • 4
  • 30
  • 53