Извлечь дату на португальском языке из String Java

Я хотел бы извлечь данные из строки, и эта строка иногда отображается по-разному. Например, это может быть любое из следующего:

Portaria n° 200, 28 de janeiro de 2018.

Portaria n° 200, 28 de janeiro de 2018 da Republica Brasileira.

Portaria n° 200 28 de janeiro de 2018.

Portaria n° 200 2017/2018 de 28 de janeiro de 2018.

Нет рисунка. Я пробовал xsplit: в некоторых случаях он работает, но не всегда.

    String receberTextoIdentifica = (xmlUtil.xpathElement(documentOrigem, Constantes.GETIDENTIFICACAO).getTextContent());
    LocalDateTime receberDataEnvio = materiaDto.getDataEnvio();
    Integer receberDataEnvioAno = receberDataEnvio.getYear();
    if (receberTextoIdentifica != null && receberTextoIdentifica.toLowerCase().contains("" + receberDataEnvioAno)) {
        Element dataTexto = documentDestino.createElement("dataTexto");
        estruturas.appendChild(dataTexto);
        receberTextoIdentifica = receberTextoIdentifica.substring(0, receberTextoIdentifica.indexOf("" + receberDataEnvioAno) + 4);
        String words[] = receberTextoIdentifica.split(" ");
        String lastFive = words[words.length - 5] + " " + words[words.length - 4] + " " + words[words.length - 3] + " "
                + words[words.length - 2] + " " + words[words.length - 1];
        dataTexto.setTextContent(lastFive);

Какие данные вы пытаетесь извлечь из этих строк? Приведите пример.

CodeIt 27.12.2018 14:17

Я хочу извлечь дату "28 de janeiro de 2018" @codelt

Philippe Sousa 27.12.2018 14:19

«28 de janeiro de 2018» всегда будет фиксированной строкой или изменится ..

Rajas 27.12.2018 14:20

Используйте String str1 = "Portaria n° 200, 28 de janeiro de 2018"; String str1_array [] = str1.split(" ");. Функция split создает массив слов из строки. Затем вы можете написать код для извлечения необходимых данных из массива строк.

CodeIt 27.12.2018 14:23

@Rajas этот шаблон всегда будет одинаковым, просто изменится дата, например «24 сентября 2018 года» или «15 ноября 2017 года».

Philippe Sousa 27.12.2018 14:24

@Codelt я использую, но не работает для меня, потому что я получаю строку разными способами, поэтому у меня нет шаблона

Philippe Sousa 27.12.2018 14:28

@PhilippeSousa Создайте еще один массив строк с названиями месяцев на португальском языке. Прокрутите каждое слово в результирующем массиве строк, полученном с помощью функции разделения, и сопоставьте его с названиями месяцев. Когда вы найдете совпадение, возьмите этот номер индекса. и создать строку, объединяющую str[index-2] + str[index-1] + str[index] + str[index+1] + str[index+2]. Это, вероятно, должно вам помочь.

CodeIt 27.12.2018 14:32

Вы можете изучить это: stackoverflow.com/questions/13367066/date-extraction-from-te‌ xt

Nikhil 27.12.2018 14:32

Вам нужно использовать регулярное выражение. Это даст вам представление о stackoverflow.com/questions/15491894/…

Sergio Muriel 27.12.2018 14:37
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
9
221
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Сначала используйте регулярное выражение для поиска даты в строке, затем используйте DateTimeFormatter для разбора ее на LocalDate:

    Pattern datePattern = Pattern.compile("\\d{1,2} de [a-zç]{4,9} de \\d{4}");
    DateTimeFormatter portugueseDateFormatter
            = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
                    .withLocale(Locale.forLanguageTag("pt-BR"));

    String[] differentStrings = {
            "Portaria n° 200, 28 de janeiro de 2018.",
            "Portaria n° 200, 28 de janeiro de 2018 da Republica Brasileira.",
            "Portaria n° 200 28 de janeiro de 2018.",
            "Portaria n° 200 2017/2018 de 28 de janeiro de 2018."
    };

    for (String s : differentStrings) {
        Matcher m = datePattern.matcher(s);
        if (m.find()) {
            String dateString = m.group();
            LocalDate date = LocalDate.parse(dateString, portugueseDateFormatter);
            System.out.println("Date found: " + date);
        } else {
            System.out.println("No date found in " + s);
        }
    }

Выход:

Date found: 2018-01-28
Date found: 2018-01-28
Date found: 2018-01-28
Date found: 2018-01-28

Регулярное выражение принимает одну или две цифры для дня месяца, затем de (с пробелами до и после), от четырех до девяти строчных букв названия месяца, включая ç, как в março (март), de снова и четырехзначный год.

Вы, вероятно, захотите поймать DateTimeParseException при синтаксическом анализе и, возможно, даже попробовать снова find, чтобы увидеть, наступит ли реальная дата позже в строке.

Если вы откроете это заново, я смогу опубликовать альтернативное решение. repl.it/repls/SplendidEthicalObjects

CodeIt 27.12.2018 14:52

@CodeIt Пожалуйста, сделайте это. Этот был на границе очень точного дубликата, поэтому я полагаю, что ваше решение здесь имеет больше смысла, чем как ответ на оригинал, на который я ссылался. Я знаю, что отвечать и закрывать - это в любом случае плохой стиль - я обнаружил оригинал только после того, как опубликовал свой ответ. Прости.

Ole V.V. 27.12.2018 14:55

Спасибо! Размещено здесь.

CodeIt 27.12.2018 15:12

Спасибо, очень помогло! Я сделал что-то очень похожее ... Matcher m = Pattern.compile ("([0-9] {1,2} \\ s + d \\ s? E? \\ s + \\ &? \\ &? [ a-zà-ü] {‌ 4,9} \\ s + de \\ s + [0-9] {‌ 4} \\ ,?) ", Pattern.CASE_INSENSITIVE) .matcher (ReceberTextoIdentifica);

Philippe Sousa 27.12.2018 16:07

Мне нужно включить это «28 de janeiro de 2018» в мой тег xml с месяцем. Я не могу использовать синтаксический анализ с этим форматом .... Спасибо большое !!

Philippe Sousa 27.12.2018 16:09

Просто любопытно, @PhilippeSousa, что такое \\&?\\&?? Спасибо за отчет.

Ole V.V. 27.12.2018 16:29

Альтернативный способ один, предложенный @Ole.

Метод получает данные из строки как есть, не конвертируя их в объект даты.

Код:

import java.util.Scanner;
import java.util.Arrays;
import java.util.List;

class Main {

  public static void main(String[] args) {

  String[] strs = {
            "Portaria n° 200, 28 de janeiro de 2018",
            "Portaria n° 200, 28 de janeiro de 2018 da Republica Brasileira",
            "Portaria n° 200 28 de janeiro de 2018",
            "Portaria n° 200 2017/2018 de 25 de janeiro de 2018"
    };

    String months[] = {"janeiro", "fevereiro", "marco", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"};

    int i,j; 

    for(i = 0; i < strs.length; i++) {
      String test_array [] = strs[i].split(" ");

      for (j = 3; j < test_array.length - 2; j++) {
        if (Arrays.asList(months).contains(test_array[j])) {
          System.out.println(test_array[j-2]+ " " + test_array[j-1]+" " +test_array[j]+ " " +test_array[j+1]+ " " +test_array[j+2]);
        }
      }
    }
  }
}

Вывод:

28 de janeiro de 2018
28 de janeiro de 2018
28 de janeiro de 2018
25 de janeiro de 2018

Смотрите это в действии здесь.

Большое спасибо!! Я попробую !!

Philippe Sousa 27.12.2018 16:08

@ OleV.V. Спасибо за вашу поддержку.

CodeIt 28.12.2018 09:52

Я немного сомневаюсь в голосовании. Это, безусловно, правильный ответ. Я по-прежнему считаю, что даты лучше помещать в объекты LocalDate, а не в строки (за исключением некоторых программ типа «запустить один раз и выбросить»). В любом случае хорошо иметь разные решения для рассмотрения и выбора. Преимущество в том, что вы больше следуете методике ОП.

Ole V.V. 28.12.2018 09:55

@ OleV.V. Вы абсолютно правы, но ОП его приняла. Фактически OP попытался использовать аналогичный метод String lastFive = words[words.length - 5] + " " + words[words.length - 4] + " " + words[words.length - 3] + " " + words[words.length - 2] + " " + words[words.length - 1];, но не смог правильно определить шаблон. У меня нет большого опыта написания java-кода, я никогда не думал о другом способе решения этой проблемы.

CodeIt 28.12.2018 09:58

Другие вопросы по теме