Сравните строку со значениями со строкой с заполнителями, чтобы найти из нее значения

#java

#java

Вопрос:

У меня есть шаблон, как показано ниже

 Hello {user}, your  request id is {id}, -------1
 

И у меня есть текст со значениями, заполненными в нем, как

 Hello ABC , your  request id is 1234.  --------2 
 

Теперь ввод в мою программу равен 2, и я хочу получить такие значения, как

  {user} = ABC
 {id}   = 1234
 

Не могли бы вы предложить мне какое-либо решение вышеуказанной проблемы. Заранее спасибо.

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

Ответ №1:

Если вы хотите использовать шаблон для выполнения синтаксического анализа, вы можете выполнить следующие действия:

 public static void main(String[] args) {
    String template = "Hello {user}, your  request id is {id}.";
    String withValues = "Hello ABC , your  request id is 1234.";

    String patternFromTemplate = template.replaceAll("\.", "\\."); // escape "." 
    patternFromTemplate = patternFromTemplate.replace("{user}", "(.*)"); // capturing group 1
    patternFromTemplate = patternFromTemplate.replace("{id}", "(.*)"); // capturing group 2

    Pattern p = Pattern.compile(patternFromTemplate);
    Matcher m = p.matcher(withValues);
    if (m.matches()) {
        System.out.println("{user} = " m.group(1));
        System.out.println("{id}   = " m.group(2));
    } 
}
 

Но будьте осторожны с символами (например . ) в вашем шаблоне, которые имеют особое значение, когда строка используется в качестве регулярного выражения. И обратите внимание, что это будет нарушено, если ваш шаблон значительно изменится (например, если id он будет первым id или user вообще не появится в шаблоне).

Что он делает:

  • Экранируйте все . символы в шаблоне, чтобы они не испортили регулярное выражение
  • Замените {user} в шаблоне на (.*) (захват группы 1)
  • Замените {id} в шаблоне на (.*) (захват группы 2)
  • Примените регулярное выражение к вашей строке со значениями
  • Извлеките совпадения (если регулярное выражение совпадает)

В основном то же самое, что предложил @zx81, единственное отличие заключается в том, что здесь регулярное выражение создается динамически на основе шаблона.

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

1. Спасибо, mth, не могли бы вы немного объяснить. Это отлично работает.

2. Большое спасибо за объяснение.

Ответ №2:

Используйте это, чтобы записать строки в группы 1 и 2, а затем извлечь:

 Hello ([^,] ), your request id is ([^.] )
 

Смотрите демонстрацию.

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

Пример кода

 String userName = null;
String userID = null;
Pattern regex = Pattern.compile("Hello ([^,] ), your request id is ([^.] )");
Matcher regexMatcher = regex.matcher(subjectString);
if (regexMatcher.find()) {
    userName = regexMatcher.group(1);
    userID = regexMatcher.group(2);
    } 
 

Объяснение

  • Hello совпадения Hello и один пробел
  • Круглые скобки в ([^,] ) capture группируют 1 любые символы, которые не являются запятыми
  • , your request id is соответствие буквальному символу
  • ([^.] ) записывайте в группу 1 любые символы, которые не являются точкой.

Это предполагает, что после вашего идентификатора будет точка, так как в Hello ABC, your request id is 1234. противном случае мы меняем разделитель.

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

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

2. Не уверен, что понимаю. 🙂 Вы отметили свой вопрос regex и сказали: «Я слаб в регулярных выражениях». Не могли бы вы объяснить немного больше?

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

4. Хорошо, я неправильно понял. Пожалуйста, взгляните на решение @mth 🙂