Mohammad
Mohammad

Reputation: 3547

regex to test space separated characters

I want to make a regex that validates "human readable" time format, where it should looks like this:

1w 1d 1h 1m

and the accepted time units are (in-case sensitive):

each time unit is optional and should be existed only once at most, so the following formats should be also (for example):

and this is what I tried so far:

/((\dw) (\dd) (\dh) (\dm))/i

the above expression will validate all of the lists formats, but it will neglect the spaces between time units, I want to make the space mandatory between a time unit and another.

Upvotes: 1

Views: 447

Answers (5)

revo
revo

Reputation: 48711

For validating those strings you need a more comprehensive regular expression. The following regex matches at both ends of input string and ensures repeating letters are not going to happen using a negative lookahead:

^(?!.*([wdhml]).*\1)\d*\.?\d+[wdhml](?: \d*\.?\d+[wdhml])*$

\d*\.?\d+ is used to allow decimals e.g. 1.5 or .5 (but care it doesn't allow 1.)

See live demo here

A shorter revision but less readable one of above regex is (credits of such mixing goes to @bobblebubble):

^(?:\d*\.?\d+([wdhml])(?!.*\1)(?: (?=.)|$))+$

Upvotes: 3

yunzen
yunzen

Reputation: 33439

console.clear();
dates = [
  // true
  "4w 1m",
  "4w 3d 2h 1m",
  "3d",
  "2h",
  "1m",
  "3d 2h",
  // false
  "4w3d",
  "2h 3d",
  "42",
  "Lorem ipsum",
  "4w 3d 2h 2h",
  "1m 1m"
];


reg = /^\s*(\d{1,2}w\s+)?(\d{1,2}d\s+)?(\d{1,2}h\s+)?(\d{1,2}m\s+)?$/;

dates.forEach(function(item, index, arr) {
  console.log(item, this.test(item))
}, reg)

Upvotes: 1

Matt.G
Matt.G

Reputation: 3609

Try Regex: ^(?=.*\d[wdhm])(?:\dw)?(?: ?(?<=^| )(?:\dd))?(?: ?(?<=^| )(?:\dh))?(?: (?<=^| )(?:\dm))?$

Demo

Upvotes: 0

Aziz.G
Aziz.G

Reputation: 3721

const regex = /^(\d+w\s?)?(\d+d\s?)?(\d{1,2}h\s?)?(\d{1,2}m)?$/

const text = "1w 8d 1h 5m"

console.log(text.match(regex)["input"])

console.log(regex.test(text))

^(\d+w\s?)?(\d+d\s?)?(\d{1,2}h\s?)?(\d{1,2}m)?$

Upvotes: 3

Avraham
Avraham

Reputation: 938

Try this one:

regex = /\b\d[wdhm]{1}\b/ig;
match = '1w 1h 1d'.match(regex);
console.log(match)

\b matches a word boundary.

See the docs

Upvotes: 0

Related Questions