JAVA регулярное выражение, чтобы содержать слова с точкой в ​​середине букв и содержать специальные слова с точкой - PullRequest
0 голосов
/ 20 апреля 2020

У меня 2 проблемы. Во-первых, 1) как я могу содержать слова с точкой между двумя буквами, например, "C .J Johnson" и 2-й, 2) возможно ли составить список слов, содержащий точку, и мое регулярное выражение будет включать их? В основном я хочу найти текстовый файл со словами и перечислить все предложения, содержащие эти слова. Мой код:

public void search_sentences() throws FileNotFoundException, IOException {
        //FileReader fr1 = new FileReader(get_File());
        BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream(get_File()),  "UTF-8"));
        ArrayList<String> words = new ArrayList();
        PrintWriter writer = new PrintWriter("rivit.txt", "UTF-8");
        String str="";
        //String [] words = {};
        String sanat = get_Text();
        for(String w: sanat.split(", ")){
            words.add(w);
        }
        String word_re = words.get(0);

        for (int i = 1; i < words.size(); i++)
                word_re += "|" + words.get(i);
            word_re = "[^.!?]*\\b(" + word_re + ")\\b[^.!?]*[.!?]";
            while(br1.ready()) { str += br1.readLine(); }
            Pattern re = Pattern.compile(word_re, 
                    Pattern.MULTILINE | Pattern.COMMENTS | 
                    Pattern.CASE_INSENSITIVE);
            Matcher match = re.matcher(str);
            String sentenceString="";
            while (match .find()) {
                sentenceString = match.group(0);
                if(!txtFile.isSelected()){
                tekstiAlue.append(sentenceString);
                } else {
                    writer.println(sentenceString);
                }

            }
        writer.close();

    }

Первый вопрос выполним, я думаю. Я пытался добавить // s к различным позициям в

"[^.!?]*\\b(" + word_re + ")\\b[^.!?]*[.!?]"

Во втором я совсем не уверен. Пример для второго: Мой текстовый файл содержит предложение «Сегодня был веселый день, например, мы играли в футбол», и я ищу по ключевому слову «весело». Теперь он должен вернуть все предложение, включая «exmpl». потому что я перечислил это слово в какой-то список раньше. Возможно ли это?

РЕДАКТИРОВАТЬ Для второго вопроса я попытался: 1. Добавить специальные слова в список и экранировать точку после них String [] saanat ={"esim\\.","yms\\.","jne\\.","tms\\.","etc\\."}; 2. Добавить word_re с помощью spe c слова, включая точки for(String x : saanat) word_re += "|" + x;

И дело не выполнилось. Идеи?

1 Ответ

0 голосов
/ 21 апреля 2020

Как сказал Джефф Холт в комментарии : «Посмотрите на Pattern.quote()»:

[...] создает строку, которая может использоваться для создания шаблона, который будет соответствовать строке s, как если бы это был буквальный шаблон.

Метасимволам или escape-последовательностям во входной последовательности не будет придано никакого специального значения.

Регулярное выражение в вопросе использует [^.!?]*, чтобы сопоставить любой символ в предложении, который не является символом конца предложения (., ! или ?).

Однако мы хотим чтобы сопоставить полные предложения со специальными «словами», такими как i.e., e.g. и etc., поэтому нам нужно увеличить это значение до (i.e.|e.g.|etc.|[^.!?])*, за исключением того, что мы должны экранировать (\) специальные символы регулярного выражения (например, .) в этих специальных словах.

Мы можем использовать Pattern.quote() для этого, а также для самого поискового слова.

public static List<String> findSentencesContaining(String fullText, String word, String[] specials) {
    Pattern p = buildRegexToFindSentencesContaining(word, specials);
    List<String> sentences = new ArrayList<>();
    for (Matcher m = p.matcher(fullText); m.find(); )
        sentences.add(m.group().replaceAll("\\s+", " ").trim()); // normalize group of whitespace into a single space
    return sentences;
}
public static Pattern buildRegexToFindSentencesContaining(String word, String[] specials) {
    StringJoiner regexText = new StringJoiner("|", "(?:", "|[^.!?])*").setEmptyValue("[^.!?]*");
    for (String s : specials)
        regexText.add(toWordRegex(s));
    String regex = regexText + toWordRegex(word) + regexText + "[.!?]";
    return Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
}
private static String toWordRegex(String word) {
    String regex = Pattern.quote(word);
    if (word.matches("\\b.*"))
        regex = "\\b" + regex;
    if (word.matches(".*\\b"))
        regex = regex + "\\b";
    return regex;
}

Тест

String fullText = "This is a test. We're testing that sentences\n" +
                  "can span multiple lines, i.e. that line" +
                  "terminators can appear in a sentence. We're\n" +
                  "also testing that sentences can contain\n" +
                  "special words containing sentence-ending\n" +
                  "\"words\", e.g. \"i.e.\" and \"etc.\". In\n" +
                  "addition, (special) word matching is\n" +
                  "case-insensitive.";
String[] specials = { "i.e.", "e.g.", "etc." };
for (String word : new String[] { "test", "also", "we're", "is", "happy" }) {
    System.out.println("Sentences containing word \"" + word + "\":");
    List<String> sentences = findSentencesContaining(fullText, word, specials);
    if (sentences.isEmpty())
        System.out.println("  ** NOT FOUND");
    else {
        for (String sentence : sentences)
            System.out.println("  " + sentence);
    }
}

Выход

Sentences containing word "test":
  This is a test.
Sentences containing word "also":
  We're also testing that sentences can contain special words containing sentence-ending "words", e.g. "i.e." and "etc.".
Sentences containing word "we're":
  We're testing that sentences can span multiple lines, i.e. that lineterminators can appear in a sentence.
  We're also testing that sentences can contain special words containing sentence-ending "words", e.g. "i.e." and "etc.".
Sentences containing word "is":
  This is a test.
  In addition, (special) word matching is case-insensitive.
Sentences containing word "happy":
  ** NOT FOUND
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...