in libraries/bot-dialogs/src/main/java/com/microsoft/recognizers/text/datetime/extractors/BaseDateTimePeriodExtractor.java [333:463]
private List<Token> matchTimeOfDay(String input, LocalDateTime reference, List<ExtractResult> dateErs) {
List<Token> results = new ArrayList<>();
Match[] matches = RegExpUtility.getMatches(config.getSpecificTimeOfDayRegex(), input);
for (Match match : matches) {
results.add(new Token(match.index, match.index + match.length));
}
// Date followed by morning, afternoon or morning, afternoon followed by Date
if (dateErs.size() == 0) {
return results;
}
for (ExtractResult er : dateErs) {
String afterStr = input.substring(er.getStart() + er.getLength());
Optional<Match> match = Arrays.stream(RegExpUtility.getMatches(config.getPeriodTimeOfDayWithDateRegex(), afterStr)).findFirst();
if (match.isPresent()) {
// For cases like "Friday afternoon between 1PM and 4 PM" which "Friday afternoon" need to be extracted first
if (StringUtility.isNullOrWhiteSpace(afterStr.substring(0, match.get().index))) {
int start = er.getStart();
int end = er.getStart() + er.getLength()
+ match.get().getGroup(Constants.TimeOfDayGroupName).index
+ match.get().getGroup(Constants.TimeOfDayGroupName).length;
results.add(new Token(start, end));
continue;
}
String connectorStr = afterStr.substring(0, match.get().index);
// Trim here is set to false as the Regex might catch white spaces before or after the text
boolean isMatch = RegexExtension.isExactMatch(config.getMiddlePauseRegex(), connectorStr, false);
if (isMatch) {
String suffix = StringUtility.trimStart(afterStr.substring(match.get().index + match.get().length));
Optional<Match> endingMatch = Arrays.stream(RegExpUtility.getMatches(config.getGeneralEndingRegex(), suffix)).findFirst();
if (endingMatch.isPresent()) {
results.add(new Token(er.getStart(), er.getStart() + er.getLength() + match.get().index + match.get().length));
}
}
}
if (!match.isPresent()) {
match = Arrays.stream(RegExpUtility.getMatches(config.getAmDescRegex(), afterStr)).findFirst();
}
if (!match.isPresent() || !StringUtility.isNullOrWhiteSpace(afterStr.substring(0, match.get().index))) {
match = Arrays.stream(RegExpUtility.getMatches(config.getPmDescRegex(), afterStr)).findFirst();
}
if (match.isPresent()) {
if (StringUtility.isNullOrWhiteSpace(afterStr.substring(0, match.get().index))) {
results.add(new Token(er.getStart(), er.getStart() + er.getLength() + match.get().index + match.get().length));
} else {
String connectorStr = afterStr.substring(0, match.get().index);
// Trim here is set to false as the Regex might catch white spaces before or after the text
if (RegexExtension.isExactMatch(config.getMiddlePauseRegex(), connectorStr, false)) {
String suffix = afterStr.substring(match.get().index + match.get().length).replaceAll("^\\s+", "");
Optional<Match> endingMatch = Arrays.stream(RegExpUtility.getMatches(config.getGeneralEndingRegex(), suffix)).findFirst();
if (endingMatch.isPresent()) {
results.add(new Token(er.getStart(), er.getStart() + er.getLength() + match.get().index + match.get().length));
}
}
}
}
String prefixStr = input.substring(0, er.getStart());
match = Arrays.stream(RegExpUtility.getMatches(config.getPeriodTimeOfDayWithDateRegex(), prefixStr)).findFirst();
if (match.isPresent()) {
if (StringUtility.isNullOrWhiteSpace(prefixStr.substring(match.get().index + match.get().length))) {
String midStr = input.substring(match.get().index + match.get().length, er.getStart());
if (!StringUtility.isNullOrEmpty(midStr) && StringUtility.isNullOrWhiteSpace(midStr)) {
results.add(new Token(match.get().index, er.getStart() + er.getLength()));
}
} else {
String connectorStr = prefixStr.substring(match.get().index + match.get().length);
// Trim here is set to false as the Regex might catch white spaces before or after the text
if (RegexExtension.isExactMatch(config.getMiddlePauseRegex(), connectorStr, false)) {
String suffix = StringUtility.trimStart(input.substring(er.getStart() + er.getLength()));
Optional<Match> endingMatch = Arrays.stream(RegExpUtility.getMatches(config.getGeneralEndingRegex(), suffix)).findFirst();
if (endingMatch.isPresent()) {
results.add(new Token(match.get().index, er.getStart() + er.getLength()));
}
}
}
}
}
// Check whether there are adjacent time period strings, before or after
for (Token result : results.toArray(new Token[0])) {
// Try to extract a time period in before-string
if (result.getStart() > 0) {
String beforeStr = input.substring(0, result.getStart());
if (!StringUtility.isNullOrEmpty(beforeStr)) {
List<ExtractResult> timeErs = config.getTimePeriodExtractor().extract(beforeStr);
if (timeErs.size() > 0) {
for (ExtractResult timeEr : timeErs) {
String midStr = beforeStr.substring(timeEr.getStart() + timeEr.getLength());
if (StringUtility.isNullOrWhiteSpace(midStr)) {
results.add(new Token(timeEr.getStart(), timeEr.getStart() + timeEr.getLength() + midStr.length() + result.getLength()));
}
}
}
}
}
// Try to extract a time period in after-string
if (result.getStart() + result.getLength() <= input.length()) {
String afterStr = input.substring(result.getStart() + result.getLength());
if (!StringUtility.isNullOrEmpty(afterStr)) {
List<ExtractResult> timeErs = config.getTimePeriodExtractor().extract(afterStr);
for (ExtractResult timeEr: timeErs) {
String midStr = afterStr.substring(0, timeEr.getStart());
if (StringUtility.isNullOrWhiteSpace(midStr)) {
results.add(new Token(result.getStart(), result.getStart() + result.getLength() + midStr.length() + timeEr.getLength()));
}
}
}
}
}
return results;
}