Средство определения шаблонных строк, которые управляют разбором и форматированием произвольных объектов? - PullRequest
6 голосов
/ 26 июня 2009

Я создаю универсальный инструмент перевода данных для внутреннего корпоративного использования, используя Java 5. Различные отделы используют разные форматы для координатной информации (широты / долготы), и они хотят видеть данные в своем собственном формате. Например, координаты Белого дома в формате DMS:

38 ° 53 '55,133 "N, 77 ° 02' 15,691" W

Но также может быть выражено как:

385355.133 / -0770215,691

Я хочу представить шаблон, требуемый каждой системой, в виде строки, а затем использовать эти шаблоны для анализа данных экземпляра из системы ввода, а также использовать этот шаблон при форматировании строки для использования системой вывода.

Так что это мало чем отличается от проблемы форматирования даты / времени, для которой JDK предоставляет java.text.SimpleDateFormat, которая позволяет вам конвертировать различные шаблоны даты / времени, которые определяются строками, такими как «YYYY-MM-DD» или "ММ / ДД / ГГ".

Мой вопрос заключается в том, должен ли я создать этот объект CoordinateFormat полностью с нуля, или есть хороший общий инструмент или четко определенный подход, который я могу использовать, чтобы направлять меня в этом деле?

Ответы [ 6 ]

1 голос
/ 10 сентября 2009

Если я правильно прочитал, вы говорите о проблеме, решаемой шаблоном Интерпретатор , но в некотором роде.

Есть несколько простых способов получить приятные универсальные интерфейсы, чтобы вы могли запустить остальную часть. Моя рекомендация на это что-то вроде:

public interface Interpreter<OutputType> {
public void setCode(String coding);
public OutputType decode(String formattedData);
public String encode(OutputType rawData); }

Однако есть несколько препятствий с конкретными реализациями. Например, вам может потребоваться указать «9/9/09», «9 сентября 09», «9 сентября 2009 года». Первый «вид» даты прост - числа и набор символов делителя, но любой из двух других довольно неприятен. Честно говоря, делать что-то совершенно общее (которое уже можно было бы консервировать), вероятно, нецелесообразно, поэтому я рекомендую следующее.

Я бы атаковал его на двух уровнях, первый из которых довольно прост с регулярным выражением и форматной строкой: объединение строки данных в вещи, которые собираются стать необработанными данными. Вы должны указать что-то вроде «D * / M * / YY» (или «M * / D *») для первого, «D * MMM YY» для второго и «Mm + D * e *, YYYY» для последнего, где вы определили в своих данных некоторые зарезервированные символы (D, M, Y, очевидные интерпретации) и для всех типов данных (* возможно несколько символов, + "полный" вывод, e определены посторонние символы) - эти символы очевидно, быть конкретным для вашего приложения. Затем ваш материал для регулярных выражений будет скомпоновывать строку, передавая все, что связано с каждым зарезервированным символом, в отдельные поля данных и сохраняя часть оформления (запятые и т. Д.) В некоторой строке форматирования.

Этот первый уровень может быть достаточно общим - каждый тип данных (например, дата, координата, адрес) имеет зарезервированные символы (которые не пересекаются ни с какими символами форматирования), а все типы данных имеют некоторые общие символы. Возможно, интерфейс Интерпретатора также будет иметь методы public List<Character> reservedSymbols() и public void splitCode(List<String> splitcodes) или, возможно, гарантированные поля, чтобы вы могли сделать разделитель внешним классом и передать результаты.

Второй уровень не так прост, потому что он касается той части, которая не может быть общей. На основе формата зарезервированных символов отдельные поля должны знать, как представлять себя. В примере с датой MM сообщит месяцу, который будет напечатан как (01, 02, ... 12), M * как (1, 2, ... 12), MMM как (JAN, FEB, ... DEC) Ммм, как (январь, февраль, ... дек) и т. Д. Если ваша компания была несколько последовательной или не отходит слишком далеко от стандартных представлений материала, то ручное кодирование каждого из них не должно быть слишком плохим (и на самом деле, в каждом типе данных, вероятно, есть разумные способы уменьшить количество реплицируемого кода). Но я не думаю, что практично обобщать все эти вещи - я имею в виду, фактически представляя то, что может быть представлено в виде числа или символов (например, месяцев) или целых данных, которые могут быть выведены из частичных данных (например, столетие из года ) или как получить усеченные представления из данных (например, усечение для года до последних двух цифр, а большинство нормальных чисел усекается до двух старших цифр), вероятно, займет столько же времени, сколько и почерк в этих случаях, хотя, думаю, я могу Представьте себе случаи вашего приложения, компромисс может стоить того. Дата - действительно хитрый пример, но я, безусловно, вижу такие же хитрые вещи для других типов данных.

Резюме:

- это простое общее лицо, которое вы можете обозначить своей проблемой, поэтому остальная часть вашего приложения может быть закодирована вокруг него.

- существует довольно простой и общий разбор первого прохода, имеющий универсальные зарезервированные символы, а затем зарезервированные символы для каждого типа данных; убедитесь, что они не сталкиваются с символами, которые будут отображаться при форматировании

- есть несколько утомительный финальный этап кодирования для отдельных битов данных

0 голосов
/ 03 сентября 2009

Класс TextTemplate в wicket генерирует строку путем интерполяции строки «шаблона» с картой пар ключ-значение. Вы можете использовать выходную строку шаблона в качестве основы с переменной для интерполяции с карты для каждого значения (градусы долготы, минуты, что угодно). Это не сделает двустороннее преобразование, но вы можете взглянуть на него и посмотреть, поможет ли оно вам.

http://wicketstuff.org/wicket13doc/org/apache/wicket/util/template/TextTemplate.html

Вот источник, из их svn:

http://svn.apache.org/repos/asf/wicket/trunk/wicket/src/main/java/org/apache/wicket/util/template/TextTemplate.java

0 голосов
/ 02 сентября 2009

Мне кажется, вы ищете более масштабную платформу для своего решения.

Основная проблема, которую я вижу, заключается в том, что вы ищете серебряную пулю, чтобы выбить любой тип данных.Но, как и в Java, самый последовательный способ - это обернуть регулярное выражение.Каждый тип объекта будет нуждаться в списке строк, определяющих принятые форматы.Таким образом, у даты может быть много, у координат - 2 и т. Д.

Эти строки могут быть регулярными (болезненными, но последовательными и принятыми), или вы можете написать свою собственную библиотеку преобразования, чтобы получить что-то вроде этого:* Конвертер c = новый конвертер ();FormatString format = new FormatString ("ddmmss.sss");format.AddRegexEquivalent ( "d", "\\ d");format.AddRegexEquivalent ( "м", "\\ д");format.AddRegexEquivalent ( "s", "\\ д");c.AddFormatString (формат);if (c.ConvertString ("385355.133")){System.out.println (c.GetData ("d"));System.out.println (c.GetData ("m"));System.out.println (c.GetData ("s"));}


вывод:385355,133

Это будет тяжело, но я думаю, это больше того, что вы ищете.Конвертер должен переводить данные буквы в регулярные выражения.(в качестве начала вы можете просто массово заменить), а затем объединить все значения для каждой буквы.Я бы возвратил String из GetData, а затем использовал бы Parse ***, который легче обрабатывать.

0 голосов
/ 26 июня 2009

Одним из решений будет определение системы спецификации, из которой могут быть получены как входное регулярное выражение (или что-то еще), так и строка выходного формата. Если у вас есть система регулярных выражений, которая позволяет именованные группы захвата, и система форматирования, которая допускает непоследовательные аргументы, это может быть так же просто, как перекодирование экранирования и индексации одного в другой. Я не знаю, почему я оставляю подробности читателю.

0 голосов
/ 26 июня 2009

# 1. Я думаю, что определение общего внутреннего формата было бы полезно. Вы должны конвертировать из входного формата во внутренний и в любое количество форматов в соответствии с требованиями вывода. # 2. RegEx будет моим выбором для реализации конвертера.

0 голосов
/ 26 июня 2009

взгляните на JScience , в частности этот класс

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...