#java #regex
#java #регулярное выражение
Вопрос:
У нас есть имена файлов, которые содержат список их идентификаторов и значений, разделенных символами подчеркивания. Сначала это казалось простым для анализа с помощью регулярного выражения, но проблема в том, что как идентификаторы, так и значения могут содержать что угодно. Тем не менее, у меня есть доступ к списку идентификаторов. Вот пример:
Идентификаторы:
{PG, PGN, T, TN, Axis}
Имена файлов:
Measurement_2020-08-10 13.08.04.578_Batch counter_41.0_PGN_1338_TN_1337
Measurement_2020-08-10 13.05.15.065_Batch counter_39.0_PG_under_score_program_name_T_1337
Measurement_2020-08-10 13.05.15.065_Batch counter_39.0_Axis_unsolvable_PG_T_bla
Ожидаемые результаты:
{[PGN,1338],[T,1337]}
{[PG,under_score_program_name],[T,1337]}
ambiguous. two possible solutions {[Axis,unsolvable_PG],[T,bla]} OR {[Axis,unsolvable],[PG,T_bla]}
Как вы можете видеть, я создал некоторые из них для тестирования определенных проблемных значений. Особенно последний, где идентификатор фактически используется как часть значения…
Очевидно, что должен быть способ решить эту проблему, поскольку я могу посмотреть на это и разобраться довольно быстро, но я просто не могу придумать способ правильно разобрать это.
Добавлен тег regex, потому что это можно было бы решить с помощью одного.
Заранее благодарю вас за предложения 🙂
Комментарии:
1. Если вы можете определить это довольно быстро, вам нужно объяснить (пожалуйста, в вопросе, а не в комментариях), каковы именно правила. Почему «Ось, неразрешимая_pg», а не «Axis_unsolvable, PG»? У вас есть список идентификаторов заранее?
2. Да, я сказал об этом в своем посте. И я могу определить это довольно быстро, потому что я знаю, что это всегда должно быть KEY_VALUE_KEY2_VALUE2 и так далее.
3. Тем не менее, я не понимаю, откуда вы знаете, что это «[Axis, unsolvable_PG], [T, bla]», а не «[Axis, unsolvable], [PG, T_bla]».
4. Хороший довод. На самом деле я этого не делаю. Я предполагаю, что некоторые случаи будут неразрешимыми. Я предполагаю, что в этом случае оба решения приемлемы.
5. Мое предложение состояло бы в том, чтобы, если это вообще возможно, кодировать имена файлов по-другому, чтобы предотвратить это. Используйте знаки плюс или, если это невозможно, три последовательных подчеркивания.
Ответ №1:
обычный старый StringTokenizer…
public class FilenameParser {
private Set<String> keywords;
public FilenameParser(Set<String> keywords) {
this.keywords = keywords;
}
public Map<String,String> parse(String filename) {
Map<String, String> results = new HashMap<String, String>();
StringTokenizer tokenizer = new StringTokenizer(filename, "_");
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
nextToken(token, tokenizer, results);
}
return results;
}
private void nextToken(String token, StringTokenizer tokenizer, Map<String, String> results) {
if(keywords.contains(token)) {
boolean keywordFound = false;
String key = token;
List<String> value = new ArrayList<>();
while(tokenizer.hasMoreTokens() amp;amp; ! keywordFound ) {
token = tokenizer.nextToken();
if(keywords.contains(token)) {
keywordFound = true;
nextToken(token, tokenizer, results);
} else {
value.add(token);
}
}
results.put(key, value.stream().reduce((left, right) -> {
return left "_" right;
}).orElse(""));
}
return;
}
}
Использование:
public class Starter {
public static void main(String[] args) {
Set<String> keywords = new HashSet<String>();
keywords.addAll(Arrays.asList("PG", "PGN", "T", "TN", "Axis"));
FilenameParser parser = new FilenameParser(keywords);
Map<String,String> result = parser.parse("Measurement_2020-08-10 13.05.15.065_Batch counter_39.0_Axis_unsolvable_PG_T_bla");
System.out.println(result);
}
}
Результат: {T = bla, PG=, Axis = неразрешимо}
Комментарии:
1. В OP сказано, что результат должен быть
{T=bla,Axis=unsolvable_PG}
для этого файла.2. код можно отредактировать, чтобы соответствовать этому результату, просто верните пустой ключ из nextToken и добавьте его к предыдущим значениям… но это выглядит двусмысленно. Использование шаблона key_value_key2_value2, как указано в комментариях, PG является ключом, для которого нет значения
3. Ну, это именно проблема операционной системы — ключи и значения могут содержать символы подчеркивания.