Страницы

Поиск по вопросам

понедельник, 20 мая 2019 г.

Форматирование дат и чисел в тексте

Суть задачи: Есть текст в котором есть даты разного формата 12/9/2010, 15.09.10, 16-09-10, также есть суммы формата 2 300 530 belarusian roubles, 2 351 dollars, 232 500 blr. Нужно все даты привести к виду September 12, 2010, а из сумм, где есть belarusian roubles или blr убрать пробелы, суммы dollars оставить как есть. И вывести весь текст с форматированными датами и суммами. Для разбора текста использовать регулярные выражения. Вот что есть:
public void convertingText (String fileName){ try (BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream(fileName), StandardCharsets.UTF_8))){ String line; Pattern p = Pattern.compile("\\d?\\d[-/.]\\d?\\d[-/.]\\d\\d\\d?\\d?"); Pattern p1 = Pattern.compile("(\\d[\\d ]*\\d|\\d+) *(bel|blr)");
while ((line = reader.readLine()) != null) { Matcher m = p.matcher(line); Matcher m1 = p1.matcher(line); if (m.find()) { //Тут должно быть форматирование даты } if (m1.find()) { //Тут форматирование суммы } System.out.println(line); } } catch (FileNotFoundException e) { System.out.println("File not found."); } catch (IOException e){ e.printStackTrace(); } }
– correct dates in the format: dayXmonthXyear, where the day – one or two digits, month – one or two digits, year – two or four digits, X – the delimiter character (point, forward slash or hyphen);
Initial file in.txt I was 2 300 530 belarusian roubles and 2 351 dollars 12/9/2010. After shopping 15.09.10 I was left with 1 700 250 blr and 2 000$. After shopping 16.09.10 I was left with 1 7 00 2 500 blr. 232 500 blr and 10 blr.
Result file in.txt I was 2300530 belarusian roubles and 2 351 dollars September 12, 2010. After shopping September 15, 2010 I was left with 1700250 blr and 2 000$. After shopping September 16, 2010 I was left with 17002500 blr. 232500 blr and 10 blr. Не могу разобраться как сразу все даты привести к одному виду и как убрать пробелы.


Ответ

Исхожу из того, что проблем в поиске дат и валют в тексте у вас не возникло, это следует из вопроса.
Для того , чтобы даты привести к одному виду лично я бы сделал так:
Найденную в тексте дату передаем в такое выражение в переменной stringDate.
LocalDate parse = LocalDate.parse(stringDate, DateTimeFormatter.ofPattern("dd/M/yyyy")); После этого в переменной parse получаем дату, которую с помощью тех же паттернов легко преобразовываем в нужный нам вид с помощью такого кода
String result = parse.format(DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.ENGLISH));
Теперь в переменной result получаем дату в нужном формате.
Соответственно, вы напишите разные регулярные выражения для разных форматов дат. При парсе даты будете также использовать разные паттерны "dd.MM.yy", "dd-MM-yy" и т.д. Я думаю, что идея Вам понятна.
Что касается дат, последнее замечание... Паттерн "dd/M/yyyy" не сработает с датой 12/11/2013, потому как месяц указан здесь двумя цифрами, а не одной. Решение проблемы - написание разных регулярных выражений. Альтернатива - оценивать длину переменной типа стринг, передаваемой в паттерн, исходя из чего использовать два разных паттерна - "dd/M/yyyy" и "dd/MM/yyyy".
Что касается замены пробелов, то тут все проще. Находите нужное значение, вызываете у стринговой переменной, в которой записано найденное занчение, метод replace (" ", ""); и получаете запись без пробела.
Вот альтернатива. После выявления даты с помощью регулярки вызываете нижеописаный метод.
private String parseDate (String textDate){ String[] split = textDate.split("\\.|\\-|\\/"); Integer year = Integer.valueOf(split[2].trim()); if (year > 20 && year<1900) year = 1900 + year; else if (year < 20) year = 2000 + year; LocalDate parse =LocalDate.of(year, Integer.valueOf(split[1].trim()), Integer.valueOf(split[0].trim())); return parse.format(DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.ENGLISH)); }
Если хотите анализировать строку на наличие пробелов и т.д., то, скорее всего, проще пройтись по массиву чаров. Не очень лаконично, но есть полный контроль над результатом. Примерно так
private String convertText (String data){ StringBuilder sb = new StringBuilder(); boolean firstLatter = true; for (char ch : data.toCharArray()) { if (Character.isDigit(ch)) sb.append(ch); if (Character.isLetter(ch)) { if (firstLatter) { sb.append(" ").append(ch); firstLatter = false; } else sb.append(ch); } } return sb.toString(); }

Комментариев нет:

Отправить комментарий