private List matchTimeOfDay()

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;
    }