2015-02-09 4 views
0

У меня есть входная строка:Заменить регулярное выражение вхождений

"hello [you], this is [me]" 

У меня есть функция, которая отображает строку на строку (жёстки для простоты):

public String map(final String input) { 
    if ("you".equals(input)) { 
     return "SO"; 
    } else if ("me".equals(input)) { 
     return "Kate"; 
    } 
    ... 
} 

Что является наиболее удобный способ заменить каждое событие [(.*)?] на его соответствующее сопоставление (задается вызовом функции map)?

Если я не прав, вы не можете использовать String.replaceAll() здесь, так как мы не знаем замены заранее.

+0

Вместо этой функции вы должны использовать 'java.util.Map '. – DennisW

ответ

1

Во-первых, выражение, что у вас есть жаден. Правильное выражение для соответствия токену в квадратных скобках - \[([^\]]*)\] (обратные косые черты должны быть удвоены для Java), поскольку он избегает проходить мимо закрывающей квадратной скобки *. Я добавил группу захвата для доступа к содержимому в квадратных скобках как group(1).

Вот способ сделать то, что вам нужно:

Pattern p = Pattern.compile("\\[([^\\]]*)\\]"); 
Matcher m = p.matcher(input); 
StringBuffer bufStr = new StringBuffer(); 
boolean flag = false; 
while ((flag = m.find())) { 
    String toReplace = m.group(1); 
    m.appendReplacement(bufStr, map(toReplace)); 
} 
m.appendTail(bufStr); 
String result = bufStr.toString(); 

Demo.

* Вы можете использовать [.*?], тоже, но это неохотно выражение может вызвать откат.

+1

Вы имеете в виду 'Pattern.compile (" \\ [[^ \\] *] \\] ");', в противном случае ваш паттерн будет '' hello [you "' – ericbn

+0

@ericbn Спасибо! Я поймал эту ошибку при работе над моей демонстрацией, так что теперь она исправлена. – dasblinkenlight

+0

Спасибо. Я действительно не понял функцию appendReplacement. Теперь я делаю! –

0

Вы можете сделать что-то вроде:

String line = "hello [you], this is [me]"; 

Pattern p = Pattern.compile("\\[(.*?)\\]"); 
Matcher m = p.matcher(line); 

while (m.find()) { 
    // m.group(1) contains the text inside [] 
    // line.replace(m.group(1), yourMap.get(m.group(1))); 
    // use StringBuilder to build the new string 
} 
+0

Спасибо. Это не отвечает на весь вопрос. Как только обнаружено событие (с 'm.group (1)'), как я могу заменить его на исходном вводе его отображением? –

+0

@ KateDeens Я обновил свой ответ. – Maroun

+0

Строки неизменяемы :) 'line.replace' не повлияет на строку. – Pshemo

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