diff --git a/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs b/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs index a1b1d30260..7dfdf40417 100644 --- a/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs +++ b/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs @@ -217,7 +217,7 @@ public static class DateTimeDefinitions public const string PMTimeRegex = @"\b(?afternoon|evening|night)\b"; public const string InclusiveModPrepositions = @"(?((on|in|at)\s+or\s+)|(\s+or\s+(on|in|at)))"; public static readonly string BeforeRegex = $@"((\b{InclusiveModPrepositions}?(before|in\s+advance\s+of|prior\s+to|(no\s+later|earlier|sooner)\s+than|ending\s+(with|on)|by|till|til|until|(?as\s+late\s+as)){InclusiveModPrepositions}?\b\s*?)|(?)((?<=)|<))(\s+the)?"; - public static readonly string AfterRegex = $@"(\b{InclusiveModPrepositions}?((after|(?>=)|>)"; + public static readonly string AfterRegex = $@"(\b{InclusiveModPrepositions}?((after|(starting|beginning)(\s+on)?(?!\sfrom)|(?>=)|>)"; public const string SinceRegex = @"((\b(since|after\s+or\s+equal\s+to|starting\s+(from|on|with)|as\s+early\s+as|any\s+time\s+from)\b\s*)|(?=))"; public const string AroundRegex = @"(\b(around|circa)\s*\b)"; public const string AgoRegex = @"\b(ago|before\s+(?yesterday|today))\b"; diff --git a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java index b4ed05805a..19b3ed2092 100644 --- a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java +++ b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java @@ -697,7 +697,7 @@ public class EnglishDateTime { public static final String BeforeRegex = "((\\b{InclusiveModPrepositions}?(before|in\\s+advance\\s+of|prior\\s+to|(no\\s+later|earlier|sooner)\\s+than|ending\\s+(with|on)|by|till|til|until|(?as\\s+late\\s+as)){InclusiveModPrepositions}?\\b\\s*?)|(?)((?<=)|<))(\\s+the)?" .replace("{InclusiveModPrepositions}", InclusiveModPrepositions); - public static final String AfterRegex = "(\\b{InclusiveModPrepositions}?((after|(?>=)|>)" + public static final String AfterRegex = "(\\b{InclusiveModPrepositions}?((after|(starting|beginning)(\\s+on)?(?!\\sfrom)|(?>=)|>)" .replace("{InclusiveModPrepositions}", InclusiveModPrepositions); public static final String SinceRegex = "((\\b(since|after\\s+or\\s+equal\\s+to|starting\\s+(from|on|with)|as\\s+early\\s+as|any\\s+time\\s+from)\\b\\s*)|(?=))"; diff --git a/JavaScript/packages/recognizers-date-time/src/dateTime/baseMerged.ts b/JavaScript/packages/recognizers-date-time/src/dateTime/baseMerged.ts index ec188bc7ac..a0f583d64a 100644 --- a/JavaScript/packages/recognizers-date-time/src/dateTime/baseMerged.ts +++ b/JavaScript/packages/recognizers-date-time/src/dateTime/baseMerged.ts @@ -168,26 +168,33 @@ export class BaseMergedExtractor implements IDateTimeExtractor { let lastEnd = 0; ers.forEach(er => { let beforeStr = source.substr(lastEnd, er.start).toLowerCase(); + let isSuccess = false; let before = this.hasTokenIndex(beforeStr.trim(), this.config.beforeRegex); if (before.matched) { let modLength = beforeStr.length - before.index; er.length += modLength; er.start -= modLength; er.text = source.substr(er.start, er.length); + isSuccess = true; } - let after = this.hasTokenIndex(beforeStr.trim(), this.config.afterRegex); - if (after.matched) { - let modLength = beforeStr.length - after.index; - er.length += modLength; - er.start -= modLength; - er.text = source.substr(er.start, er.length); + if(!isSuccess){ + let after = this.hasTokenIndex(beforeStr.trim(), this.config.afterRegex); + if (after.matched) { + let modLength = beforeStr.length - after.index; + er.length += modLength; + er.start -= modLength; + er.text = source.substr(er.start, er.length); + isSuccess = true; + } } - let since = this.hasTokenIndex(beforeStr.trim(), this.config.sinceRegex); - if (since.matched) { - let modLength = beforeStr.length - since.index; - er.length += modLength; - er.start -= modLength; - er.text = source.substr(er.start, er.length); + if(!isSuccess){ + let since = this.hasTokenIndex(beforeStr.trim(), this.config.sinceRegex); + if (since.matched) { + let modLength = beforeStr.length - since.index; + er.length += modLength; + er.start -= modLength; + er.text = source.substr(er.start, er.length); + } } }); } diff --git a/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts b/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts index f84a382c43..56bfc33e68 100644 --- a/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts +++ b/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts @@ -204,7 +204,7 @@ export namespace EnglishDateTime { export const PMTimeRegex = `\\b(?afternoon|evening|night)\\b`; export const InclusiveModPrepositions = `(?((on|in|at)\\s+or\\s+)|(\\s+or\\s+(on|in|at)))`; export const BeforeRegex = `((\\b${InclusiveModPrepositions}?(before|in\\s+advance\\s+of|prior\\s+to|(no\\s+later|earlier|sooner)\\s+than|ending\\s+(with|on)|by|till|til|until|(?as\\s+late\\s+as))${InclusiveModPrepositions}?\\b\\s*?)|(?)((?<=)|<))(\\s+the)?`; - export const AfterRegex = `(\\b${InclusiveModPrepositions}?((after|(?>=)|>)`; + export const AfterRegex = `(\\b${InclusiveModPrepositions}?((after|(starting|beginning)(\\s+on)?(?!\\sfrom)|(?>=)|>)`; export const SinceRegex = `((\\b(since|after\\s+or\\s+equal\\s+to|starting\\s+(from|on|with)|as\\s+early\\s+as|any\\s+time\\s+from)\\b\\s*)|(?=))`; export const AroundRegex = `(\\b(around|circa)\\s*\\b)`; export const AgoRegex = `\\b(ago|before\\s+(?yesterday|today))\\b`; diff --git a/Patterns/English/English-DateTime.yaml b/Patterns/English/English-DateTime.yaml index 9b0e3f74ba..1aef53f3c2 100644 --- a/Patterns/English/English-DateTime.yaml +++ b/Patterns/English/English-DateTime.yaml @@ -509,8 +509,9 @@ InclusiveModPrepositions: !simpleRegex BeforeRegex: !nestedRegex def: ((\b{InclusiveModPrepositions}?(before|in\s+advance\s+of|prior\s+to|(no\s+later|earlier|sooner)\s+than|ending\s+(with|on)|by|till|til|until|(?as\s+late\s+as)){InclusiveModPrepositions}?\b\s*?)|(?)((?<=)|<))(\s+the)? references: [ InclusiveModPrepositions ] +# "starting from" is SinceRegex AfterRegex: !nestedRegex - def: (\b{InclusiveModPrepositions}?((after|(?>=)|>) + def: (\b{InclusiveModPrepositions}?((after|(starting|beginning)(\s+on)?(?!\sfrom)|(?>=)|>) references: [ InclusiveModPrepositions ] SinceRegex: !simpleRegex def: ((\b(since|after\s+or\s+equal\s+to|starting\s+(from|on|with)|as\s+early\s+as|any\s+time\s+from)\b\s*)|(?=)) diff --git a/Python/libraries/recognizers-date-time/recognizers_date_time/date_time/base_merged.py b/Python/libraries/recognizers-date-time/recognizers_date_time/date_time/base_merged.py index 6c8b62ae95..76f5db95c0 100644 --- a/Python/libraries/recognizers-date-time/recognizers_date_time/date_time/base_merged.py +++ b/Python/libraries/recognizers-date-time/recognizers_date_time/date_time/base_merged.py @@ -207,6 +207,7 @@ def add_mod(self, ers: List[ExtractResult], source: str) -> List[ExtractResult]: def add_mod_item(self, er: ExtractResult, source: str) -> ExtractResult: before_str = source[0:er.start] + is_success = False before = self.has_token_index(before_str.strip(), self.config.before_regex) if before.matched: @@ -214,20 +215,24 @@ def add_mod_item(self, er: ExtractResult, source: str) -> ExtractResult: er.length += mod_len er.start -= mod_len er.text = source[er.start:er.start + er.length] - - after = self.has_token_index(before_str.strip(), self.config.after_regex) - if after.matched: - mod_len = len(before_str) - after.index - er.length += mod_len - er.start -= mod_len - er.text = source[er.start:er.start + er.length] - - since = self.has_token_index(before_str.strip(), self.config.since_regex) - if since.matched: - mod_len = len(before_str) - since.index - er.length += mod_len - er.start -= mod_len - er.text = source[er.start:er.start + er.length] + is_success = True + + if not is_success: + after = self.has_token_index(before_str.strip(), self.config.after_regex) + if after.matched: + mod_len = len(before_str) - after.index + er.length += mod_len + er.start -= mod_len + er.text = source[er.start:er.start + er.length] + is_success = True + + if not is_success: + since = self.has_token_index(before_str.strip(), self.config.since_regex) + if not is_success and since.matched: + mod_len = len(before_str) - since.index + er.length += mod_len + er.start -= mod_len + er.text = source[er.start:er.start + er.length] return er diff --git a/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py b/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py index 1ccaf5a9c6..0f5a57d982 100644 --- a/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py +++ b/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py @@ -205,7 +205,7 @@ class EnglishDateTime: PMTimeRegex = f'\\b(?afternoon|evening|night)\\b' InclusiveModPrepositions = f'(?((on|in|at)\\s+or\\s+)|(\\s+or\\s+(on|in|at)))' BeforeRegex = f'((\\b{InclusiveModPrepositions}?(before|in\\s+advance\\s+of|prior\\s+to|(no\\s+later|earlier|sooner)\\s+than|ending\\s+(with|on)|by|till|til|until|(?as\\s+late\\s+as)){InclusiveModPrepositions}?\\b\\s*?)|(?)((?<=)|<))(\\s+the)?' - AfterRegex = f'(\\b{InclusiveModPrepositions}?((after|(?>=)|>)' + AfterRegex = f'(\\b{InclusiveModPrepositions}?((after|(starting|beginning)(\\s+on)?(?!\\sfrom)|(?>=)|>)' SinceRegex = f'((\\b(since|after\\s+or\\s+equal\\s+to|starting\\s+(from|on|with)|as\\s+early\\s+as|any\\s+time\\s+from)\\b\\s*)|(?=))' AroundRegex = f'(\\b(around|circa)\\s*\\b)' AgoRegex = f'\\b(ago|before\\s+(?yesterday|today))\\b' diff --git a/Specs/DateTime/English/DateTimeModel.json b/Specs/DateTime/English/DateTimeModel.json index ce70908e3e..cb550d034e 100644 --- a/Specs/DateTime/English/DateTimeModel.json +++ b/Specs/DateTime/English/DateTimeModel.json @@ -10699,6 +10699,66 @@ } ] }, + { + "Input": "Please can you arrange a Microsoft Teams Meeting starting January 7th to discuss ARM Templates?", + "Context": { + "ReferenceDateTime": "2019-04-24T00:00:00" + }, + "Results": [ + { + "Text": "starting january 7th", + "Start": 49, + "End": 68, + "TypeName": "datetimeV2.daterange", + "Resolution": { + "values": [ + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2019-01-07" + }, + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2020-01-07" + } + ] + } + } + ] + }, + { + "Input": "Please can you arrange a Microsoft Teams Meeting starting on January 7th to discuss ARM Templates?", + "Context": { + "ReferenceDateTime": "2019-04-24T00:00:00" + }, + "Results": [ + { + "Text": "starting on january 7th", + "Start": 49, + "End": 71, + "TypeName": "datetimeV2.daterange", + "Resolution": { + "values": [ + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2019-01-07" + }, + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2020-01-07" + } + ] + } + } + ] + }, { "Input": "Let's meet on february twenty second at 3:30", "Context": { @@ -10777,6 +10837,66 @@ } ] }, + { + "Input": "Please can you arrange a Microsoft Teams Meeting beginning January 7th to discuss ARM Templates?", + "Context": { + "ReferenceDateTime": "2019-04-24T00:00:00" + }, + "Results": [ + { + "Text": "beginning january 7th", + "Start": 49, + "End": 69, + "TypeName": "datetimeV2.daterange", + "Resolution": { + "values": [ + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2019-01-07" + }, + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2020-01-07" + } + ] + } + } + ] + }, + { + "Input": "Please can you arrange a Microsoft Teams Meeting beginning on January 7th to discuss ARM Templates?", + "Context": { + "ReferenceDateTime": "2019-04-24T00:00:00" + }, + "Results": [ + { + "Text": "beginning on january 7th", + "Start": 49, + "End": 72, + "TypeName": "datetimeV2.daterange", + "Resolution": { + "values": [ + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2019-01-07" + }, + { + "timex": "XXXX-01-07", + "Mod": "after", + "type": "daterange", + "start": "2020-01-07" + } + ] + } + } + ] + }, { "Input": "Let's meet on friday march fifteenth nine a m.", "Context": {