2014-01-07 3 views
2

Как именно вы заменяете группы, добавляя их в строковый буфер? Пример: (a) (b) (c) Как вы можете заменить группу 1 на d, группу 2 на e и так далее? Я работаю с Java regex engine. Спасибо заранее.Как вы заменяете группы в регулярном выражении?

+1

возможно дубликат [Можно ли заменить групп в Java регулярное выражение ?] (http://stackoverflow.com/questions/988655/can-i-replace-groups-in-java-regex) –

ответ

0

Вы можете использовать Matcher#start(group) и Matcher#end(group) построить общий метод замены:

public static String replaceGroup(String regex, String source, int groupToReplace, String replacement) { 
    return replaceGroup(regex, source, groupToReplace, 1, replacement); 
} 

public static String replaceGroup(String regex, String source, int groupToReplace, int groupOccurrence, String replacement) { 
    Matcher m = Pattern.compile(regex).matcher(source); 
    for (int i = 0; i < groupOccurrence; i++) 
     if (!m.find()) return source; // pattern not met, may also throw an exception here 
    return new StringBuilder(source).replace(m.start(groupToReplace), m.end(groupToReplace), replacement).toString(); 
} 

public static void main(String[] args) { 
    // replace with "%" what was matched by group 1 
    // input: aaa123ccc 
    // output: %123ccc 
    System.out.println(replaceGroup("([a-z]+)([0-9]+)([a-z]+)", "aaa123ccc", 1, "%")); 

    // replace with "!!!" what was matched the 4th time by the group 2 
    // input: a1b2c3d4e5 
    // output: a1b2c3d!!!e5 
    System.out.println(replaceGroup("([a-z])(\\d)", "a1b2c3d4e5", 2, 4, "!!!")); 
} 

Проверить online demo here.

+0

Это намного сложнее, чем нужно. См. [Ответ gtgaxiola] (http://stackoverflow.com/a/20981946/20938). –

+0

@AlanMoore 'appendReplacement()' - элегантное решение для случаев, когда достаточно простой замены. Даже в этом случае я не думаю, что мое решение сложно. Тем не менее, метод «replaceGroup()» решает гораздо более сложную задачу, чем просто заменять - и в родовом, параметризованном виде. Попытайтесь получить результаты на моем примере 'main()' с другим, и вы получите то, что я имею в виду. – acdcjunior

+0

Я думаю, что, возможно, нашел другое решение. Я пытаюсь понять, могут ли инструкции switch помочь нам каким-то образом. –

0

Вы ищете что-то в этом роде?

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

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

public class Program1 { 
    public static void main(String[] args) { 
     Pattern p = Pattern.compile("(a)(b)(c)"); 
     String str = "111abc222abc333"; 
     String out = null; 
     Matcher m = p.matcher(str); 
     out = m.replaceAll("z$3y$2x$1"); 
     System.out.println(out); 
    } 
} 

Это дает 111zcybxa222zcybxa333 как выход.
Я думаю, вы увидите, что делает этот пример.

Но хорошо, я думаю, не готовы встроенный
метода, через который вы можете сказать, например:
- заменить группу 3 с ZZZ
- заменить группу 2 с ими
- заменить группу 1 с ххм

+0

Было бы неплохо иметь лямбды для такого рода случаев? Затем вы можете запустить эти лямбды через небольшой цикл и даже использовать хеш-карты для хранения групп регулярных выражений в качестве ключей и их заменяющих шаблонов в качестве значений! Спешите JDK 8! –

+0

Перед выполнением замены вам не нужно вызывать 'find()'. Если совпадений нет, 'replaceAll()' просто возвращает исходную строку. –

+0

@AlanMoore Согласен. Обновлено. –

2

Вы можете использовать Matcher'sappendReplacement

Вот пример пример использования:

вход: «привет боб Как ваша кошка»

регулярное выражение: "(боб | кошки)"

выход: "привет алиса Как ваша собака"

public static void main(String[] args) { 
    Pattern p = Pattern.compile("(bob|cat)"); 
    Matcher m = p.matcher("hello bob How is your cat?"); 
    StringBuffer s = new StringBuffer(); 
    while (m.find()) { 
     m.appendReplacement(s, doReplace(m.group(1))); 
    } 
    m.appendTail(s); 
    System.out.println(s.toString()); 
} 


public static String doReplace(String s) { 
    if(s.equals("bob")) { 
     return "alice"; 
    } 
    if(s.equals("cat")) { 
     return "dog"; 
    } 

    return ""; 
} 
+0

+1, но вы забыли завершить его, вызвав 'appendTail()'. Я починил это. –

+0

@AlanMoore спасибо товарищу! – gtgaxiola

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