Sachila Ranawaka
Sachila Ranawaka

Reputation: 41417

regex validation from a to z with an exception of certain characters

I have a variable like this

var time = "12h 55m";

I am only allowed to use H,h,M,m characters in the string. If i have something like this

var time = "12hk 55m";

then it should produce an error. how can I validate this using regex expression.'

looking for something like this

if (stringToTest.match(/^[a-zA-Z0-9]*$/))

Upvotes: 0

Views: 71

Answers (4)

jrook
jrook

Reputation: 3519

The accepted answer apparently satisfies the OP. But I noticed that in this comment the OP says that the character symbols should not be repeated. For example, 12h 12h should be invalid but all answers match this. I don't think this can be done using only regex. So here is an alternative solution:

function timeParser(timeStr) {
  var acChars = ['h', 'H', 'm', 'M'];
  if ((timeStr.match(/\s/g) || []).length !== 1) return false;
  var tokens = timeStr.split(' ');
  for (var token of tokens) {
    var rx = new RegExp("\\d{1,3}[" + acChars.join("") + "]", "g");
    if (!token.match(rx) ||
      token.match(rx).length !== 1 ||
      token !== token.match(rx)[0]) return false;
    var tc = token.charAt(token.length - 1);
    acChars.splice(acChars.indexOf(tc), 1);
  }
  return true;
}

var timearr = ["12h 12h", "1m1h 515M", "12hk 55m", "H 12m", "m 12H", "12H 11m", "00m 001h", "20M 1"];

for (var tim of timearr)
  console.log(timeParser(tim));

and 12h 12h is not matched.

Upvotes: 0

Alessandro
Alessandro

Reputation: 4472

You could use following regex ^\d{1,2}[hmHM]\s\d{1,2}[hmHM]:

  • ^ asserts position at start of the string
  • \d matches a digit (equal to [0-9])
  • {1,2} Quantifier — Matches between 1 and 2 times, as many times as possible, giving back as needed
  • [hmHM] matches a single character in the list hmHM (case sensitive)
  • \s matches any whitespace character
  • \d{1,2}[hmHM] as described above
  • \g modifier: global. All matches (don't return after first match)

See following snippet to test it:

var regex = /^\d{1,2}[hmHM]\s\d{1,2}[hmHM]/g;

function check(par){
  console.log(par.value + " match: " + regex.test(par.value));
}
Insert a text in the input <input type="text" id="test" value="" onchange="javascript:check(this)">

Upvotes: 0

gurvinder372
gurvinder372

Reputation: 68393

Try

/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i 

It matches 2 digits followed by either h or m, followed by one or more space, followed by 2 digits followed by either h or m

Following will match

"12h 55m".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)

"12m 55h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)

"2m 55h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)

"12m 5h".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)

These will not

"122h 555m".match(/^\d{1,2}[hm]\s+\d{1,2}[hm]$/i)

Upvotes: 2

Kaivosukeltaja
Kaivosukeltaja

Reputation: 15735

The reg in regex stands for regular and your data seems to have a possibility to be irregular. I'd recommend to do the check differently but since you're looking for a regex solution:

/^(\d{2,3}h\s+\d{1,2}m)|(\d{1,2}m\s+\d{2,3}h)$/gi

This will match h and m in either order but will reject if either is in the string twice.

Upvotes: 0

Related Questions