0

I'm struggling to find a rule which will match a date pattern (and only that pattern) in between two sets of optional strings - birthday/birth/bday/born.

One or more of the strings must be present in the input before the date can be matched.

Would also need to be performed in a single Regex matching operation if possible. This is one of several expressions I need to run through a handler which expects only a single expression and no facility for additional logic.

Here's an example:

I was born on 01/01-2001

should match 01/01-2001

My bday was on 01-01-2001 which was the day I was born, obviously

should match 01-01-2001

01 01 2001 was my day of birth

should match 01 01 2001

Today’s date is 24/06/2018

should not match

So far I have this: (?<=.*born|birth|bday).*?([0-9]{2,4}[^A-Za-z0-9]+[0-9]{2,4}[^A-Za-z0-9]+[0-9]{2,4}) which works perfectly in matching the date if those strings are present before it. It doesn't match anything if I have those strings after the date.

disposedtrolley
  • 358
  • 3
  • 8

2 Answers2

2

Can something simple as this work as you want?

/\d\d\/\d\d\/\d\d\d\d/

Stack snippet

var nr1 = "I was born on 01/01/2001"
var nr2 = "My bday was on 01/01/2001 which was the day I was born, obviously"
var nr3 = "01/01/2001 was my day of birth"

console.log(nr1.match(/\d\d\/\d\d\/\d\d\d\d/));
console.log(nr2.match(/\d\d\/\d\d\/\d\d\d\d/));
console.log(nr3.match(/\d\d\/\d\d\/\d\d\d\d/));

Updated based on a comment.

If to check for both date and either of the words birth|bday|born, as simple solution could be to run 2 matches

Stack snippet

var nr1 = "I was born on 01/01/2001"
var nr2 = "My bday was on 01/01/2001 which was the day I was born, obviously"
var nr3 = "01/01/2001 was my day of birth"
var nr4 = "This is a simple date 01/01/2001"


console.log(nr1.match(/(birth|bday|born)/) &&         
            nr1.match(/\d\d\/\d\d\/\d\d\d\d/));

console.log(nr2.match(/(birth|bday|born)/) && 
            nr2.match(/\d\d\/\d\d\/\d\d\d\d/));

console.log(nr3.match(/(birth|bday|born)/) && 
            nr3.match(/\d\d\/\d\d\/\d\d\d\d/));

console.log(nr4.match(/(birth|bday|born)/) &&
            nr4.match(/\d\d\/\d\d\/\d\d\d\d/));

Updated a 2nd time based on a comment.

Merged the two matches into one regex, which this post both shows and give some great explanations to:

Stack snippet

var nr1 = "I was born on 01/01/2001"
var nr2 = "My bday was on 01/01/2001 which was the day I was born, obviously"
var nr3 = "01/01/2001 was my day of birth"
var nr4 = "This is a simple date 01/01/2001"


console.log(nr1.match(/(?=.*(birth|bday|born))(?=.*(\d\d\/\d\d\/\d\d\d\d))/));     
console.log(nr2.match(/(?=.*(birth|bday|born))(?=.*(\d\d\/\d\d\/\d\d\d\d))/));     
console.log(nr3.match(/(?=.*(birth|bday|born))(?=.*(\d\d\/\d\d\/\d\d\d\d))/));     
console.log(nr4.match(/(?=.*(birth|bday|born))(?=.*(\d\d\/\d\d\/\d\d\d\d))/));     
Asons
  • 84,923
  • 12
  • 110
  • 165
  • Sidenote: Will not work for `1/1/2001` suggest adding optional operator – Medet Tleukabiluly Jun 23 '18 at 23:50
  • @MedetTleukabiluly True, hence I asked if the given solution were enough. – Asons Jun 23 '18 at 23:55
  • Sorry I should’ve been more specific with the optional strings. A string from either set must be present in the input before the date should be matched. E.g. “the date is 24/06/2018” should not be matched. – disposedtrolley Jun 24 '18 at 00:15
  • @disposedtrolley Added a 2nd solution – Asons Jun 24 '18 at 00:52
  • @LGSon thanks! Is there a way to incorporate these into a single matching operation? I have to run these through a handler that expects only a single regex pattern to match and doesn’t accept additional logic. – disposedtrolley Jun 24 '18 at 01:03
  • @disposedtrolley Added a 3rd sample – Asons Jun 24 '18 at 01:19
  • @disposedtrolley I also added a comment at the question, as it now likely became a dupe. That dupe link also holds some great explanations. – Asons Jun 24 '18 at 01:24
1

You could first test for birth, bday or born and then match for a set of three numbers separated by a single character.

/birth|born|bday/.test(str)? str.match(/\d+.\d+.\d+/)[0] : ""

str = "I was born on 01/01-2001"
console.log(/birth|born|bday/.test(str)? str.match(/\d+.\d+.\d+/)[0] : "")

str = "01 01 2001 was my day of birth"
console.log(/birth|born|bday/.test(str)? str.match(/\d+.\d+.\d+/)[0] : "")

str = "Today’s date is 24/06/2018"
console.log(/birth|born|bday/.test(str)? str.match(/\d+.\d+.\d+/)[0] : "")
R. Schifini
  • 9,085
  • 2
  • 26
  • 32
  • Thanks! Any chance you could help me find a solution that only involves a single operation? This is one of several expressions I have to run through a handler that only accepts a single matching pattern, with no way to customise additional logic without changing the entire handler. – disposedtrolley Jun 24 '18 at 01:04