2014-10-22 2 views
0

я следующий сценарий в моем текущем проекте Java:Java: Заменить RegEx с результатом метода

Файл свойств: метод

animal1=cat 
animal2=dog 

Java,:

public String replace(String input) { 
    return input.replaceAll("%(.*?)%", properties.getProperty("$1")); 
} 

Та часть, которая говорит, что properties.getProperty("$1") явно не работает, потому что он вернет свойство для ключа «$ 1», но не для фактического значения за 1 доллар.

Есть ли простой способ заменить, например, «% animal1%» на «cat»?

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

ответ

1

Не пытайтесь сделать это как Oneliner. Если вы используете цикл для проверки всех моделей, которые могли бы соответствовать

Вот код, который будет делать трюк для вас (это должно скомпилировать и запустить как есть)

package org.test.stackoverflow; 

import java.util.Properties; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class PatternReplacer { 
    private final Pattern keyPattern = Pattern.compile("%([^%]*)%"); 
    private final Properties properties; 

    public PatternReplacer(Properties propertySeed) { 
    properties = propertySeed; 
    } 

    public String replace(String input) { 
    int start = 0; 

    while(true) { 
     Matcher match = keyPattern.matcher(input); 

     if(!match.find(start)) break; 

     String group = match.group(1); 
     if(properties.containsKey(group)) { 
     input = input.replaceAll("%" + group + "%", properties.getProperty(group)); 
     } else { 
     start = match.start() + group.length(); 
     } 
    } 

    return input; 
    } 

    public static void main(String... args) { 
    Properties p = new Properties(); 
    p.put("animal1", "cat"); 
    p.put("animal2", "dog"); 

    PatternReplacer test = new PatternReplacer(p); 
    String result = test.replace("foo %animal1% %bar% %animal2%baz %animal1% qu%ux"); 
    System.out.println(result); 
    } 
} 

Выход:

foo cat %bar% dogbaz cat qu%ux 
+0

Очень приятное решение, спасибо. Оно работает! – mtronics

+0

Я улучшил регулярное выражение на основе ответа @Pshemo (спасибо), обратите внимание на редактирование – durron597

1

Если вы правильно поняли, вам нужно будет вручную использовать методы appendReplacement и appendTail класса Matcher. Это позволит вам сдать результат properties.getProperty(matcher.group(1))

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

  • string->foo,
  • secret->whatever

и определяется простым вызовом get(keyword) из карты, которая хранит это отображение.

String data = "some string with some secret data"; 

Map<String,String> properties = new HashMap<>(); 
properties.put("string", "foo"); 
properties.put("secret", "whatever"); 

Pattern p = Pattern.compile("string|secret"); 
Matcher m = p.matcher(data); 

StringBuffer sb = new StringBuffer(); 
while (m.find()){ 
    m.appendReplacement(sb, properties.get(m.group()));//replace found match 
               //with result based on group 
} 
m.appendTail(sb);//append rest of text after last match, in our case " data" 

String result = sb.toString(); 
System.out.println("Original: " + data); 
System.out.println("Replaced: " + result); 

Результат:

Original: some string with some secret data 
Replaced: some foo with some whatever data 
+0

Он хочет, чтобы дополнительные строки были ограничены '% secret %' или что-то еще, ваш код не обрабатывает символы'% '. Он также не представляет собой шаблон регулярного выражения из объекта «Свойства». – durron597

+0

@ durron597 Мой ответ - просто пример, который можно использовать для создания правильного кода. OP уже имеет правильное регулярное выражение, которое найдет свойства - строки между '%' (''% (. *?)% "' - которые могут быть улучшены до '"% ([^%] *)% "', чтобы избежать ненужного возврата), поэтому я не добавил его к моему ответу. Также «Карта» очень похожа на «Свойства», поэтому я не вижу проблемы здесь. Опять же, мой ответ не * * решение, а руководство о том, как его создать. – Pshemo

+0

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

Смежные вопросы