Я пытаюсь получить определенные данные из проанализированных строк. Эти строки обычно соответствуют шаблону (~ 90% времени)
Пример
2 tsp ground nutmeg (this should parse to {quantity = 2.0}{units = tsp}{ingredient = ground nutmeg})
1 cup water (this should parse {quantity = 1.0}{units = cup}{ingredient = water}
Затем я анализирую строки с помощью regex или string.split (), как правило, с пробелами.
Этот шаблон я извлекаю данные в шаблон {количество} {единица} {ингредиент}.
Первая строка, разделенная пробелом, является количеством. Затем я проверяю вторую строку, отделенную пробелом, от всех стандартных единиц измерения. Затем возьмите остаток строки в качестве ингредиента. Все они затем используются для заполнения класса, называемого ингредиентом, который имеет количество, единицу измерения и ингредиент.
Проблема возникает, когда вещи не соответствуют этому шаблону.
Строки, из которых я разбираю, находятся вне моего контроля и просто даны мне, и все они важны. Поэтому я не могу выбросить строки, которые не соответствуют моему шаблону. Все, кроме строки, находится под моим контролем, поэтому я могу изменять по мере необходимости.
На ум приходят два примера:
1 egg, beaten
(not sure what i should parse this too... maybe {quantity = 1.0}{units = ""}
{ingredient = egg, beaten}
or
1 (.25 ounce) package active dry yeast
(not sure how i should parse it but should end up as {quantity = 0.25}{units = ounce}
{ingredient = active dry yeast}
В первом примере я бы проанализировал число 2 как количество, обыскал яйца по всем имеющимся у меня единицам, решил, что они не соответствуют единице, и поместил их в качестве ингредиента.
Второй пример просто ломает мой код, потому что он получает количество (1), затем ищет единицу (единственной действительной единицей является унция), а затем ставит остаток как имя ингредиента. {количество = 1} {единица = унция} {ингредиент = .25 пакет активных сухих дрожжей}, что неправильно.
Это код, который выделяет ингредиенты из строки.
public void setRecipeIngredientFromParsedString(String s)
{
String ingredientName = new String();
//gets rid of extra junk at end of string
if(!s.trim().isEmpty())
{
//split by spaces into tokens
String[] tokens = s.split(" ");
//the quantity is allowed to be a fraction.
//allowed are 1 1/2 (mixed number) 1/3 (fraction) 1 (whole number)
if (Fraction.isFraction(tokens[0])) {
this.amount.setQuantity(Fraction.parseFraction(tokens[0]).toDecimal());
} else if (Fraction.isNumber(tokens[0])) {
if (Fraction.isFraction(tokens[1])) {
this.amount.setQuantity(Fraction.parseFraction(tokens[0] + " " + tokens[1]).toDecimal());
} else {
this.amount.setQuantity(Double.parseDouble(tokens[0]));
}
}
//this could be done better. I look through all the tokens until i find one that is a unit.
// Then i set the unit and delete that token.
for (int i = 0; i < tokens.length; i++) {
for (String unit : Measurement.getAllUnits()) {
if (tokens[i].contains(unit)) {
this.amount.setUnit(tokens[i]);
tokens[i] = "";
}
}
}
//this is not quite there either. every remaining token should be the ingredient name
// but we go ahead and replace all numbers and slashes just in case.
for (String token : tokens) {
ingredientName += token + " ";
}
ingredientName = ingredientName.replaceAll("[0-9,/,(,)]", "");
this.setName(ingredientName.trim());
}
}
То, что я хочу, это некоторые идеи или предложения о том, как анализировать правильные данные в случае, когда они не совсем соответствуют нормальному шаблону. Я точно не знаю всех возможных шаблонов, которые могли бы возникнуть настолько жестко, если операторы для каждого типа вариаций кажутся плохим решением. Как бы вы справились с этими данными и получили от них соответствующую информацию?
Спасибо!
Дайте мне знать, если есть какие-либо разъяснения, которые я могу вам дать.