Как изменить текстовое содержимое с помощью некоторого измененного шаблона в Java

#java #regex

#java #регулярное выражение

Вопрос:

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

Ввод:

 I am #check Some Text/#Middle#check Text/#
  

Ожидаемый результат:

 #check Some Text is manipulated/#Middle#check Text/#
  

Фактический результат:

 #check Some Text is manipulated/##check Text/#
  

 Pattern pattern = Pattern.compile("(#check)([^/>]*)(/#)");
String line = "I am #check Some Text/#Middle#check Text/#";
String replaced = "";               
Matcher matcher = pattern.matcher(line);
while(matcher.find())
{
    if(matcher.group(2).contains("Some"))
        replaced =matcher.group(1) matcher.group(2) " is manipulated" matcher.group(3);
    else 
        replaced =matcher.group();
}
  

Любая помощь будет очень полезна.

Ответ №1:

Прежде всего, я бы рекомендовал использовать Matcher.replaceAll() вместо того, чтобы создавать строку самостоятельно. Все совпадения шаблона заменяются заданной строкой замены. Вы можете использовать группы захвата из вашего шаблона, используя $X (например $1 для первой группы) в строке замены.

Итак, ваш код будет выглядеть следующим образом:

 Pattern pattern = Pattern.compile("^. ?(?=#)(.*)(#check[^/#] Some[^/#] )(/#)(.*)");
Matcher matcher = pattern.matcher(line);
String replaced = matcher.replaceAll("$1$2 is manipulated$3$4");
System.out.println(replaced);
  

Вот некоторые результаты для заданных входных данных:

 IN:  I am #check Some Text/#Middle#check Text/#
OUT: #check Some Text is manipulated/#Middle#check Text/#4

IN:  I am #check hello there Some Text/#Middle#check Text/#
OUT: #check hello there Some Text is manipulated/#Middle#check Text/#

IN:  I am #check Text/#Middle#check Some Text/#
OUT: #check Text/#Middle#check Some Text is manipulated/#
  

Если шаблон должен соответствовать регистру без учета регистра, вы можете использовать это для его создания:

 Pattern pattern = Pattern.compile("...", Pattern.CASE_INSENSITIVE);
  

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

1. Моя проблема в том, что «некоторые» могут появляться где угодно, это не обязательно только при запуске. Ввод может быть —>>>> Я #проверяю привет, там какой-то текст / # Средний # проверяю текст / # вот почему я использовал метод line.contains()

2. @Anand Я обновил свой ответ. Надеюсь, что это работает для вас сейчас.

Ответ №2:

Вы должны использовать шаблон типа (.*)(/}.*/}) , сопоставлять до первого /} , чтобы получить то, что было до, и то, что после

 Pattern pattern = Pattern.compile("(.*)(\/}.*\/})");
String line = "I am {check Some Text/}Middle{check Text/}";
String replaced;               
Matcher matcher = pattern.matcher(line);
if(matcher.find()) {
    replaced = matcher.group(1) " is manipulated" matcher.group(2);
}else{ 
    replaced = matcher.group();
}
System.out.println(replaced)
  

> Code demo

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

1. ваша логика потерпит неудачу, если на входе будет указано I am {проверить текст /}Middle{проверить некоторый текст /}

2. @Anand вы изменили ожидаемый результат после того, как я ответил, я не смог написать что-то хорошее для решения проблемы ^^

Ответ №3:

Если вы хотите использовать регулярные выражения и Matcher s, вы можете использовать метод Matcher ‘s replaceAll() . По сути, replaceAll() заменяет соответствующий текст в его Matcher и заменяет его тем, что находится в строке, переданной replaceAll(str) . Например, вы могли бы использовать:

 matcher.replaceAll("$1$2 is manipulated$3")
  

вместо всего вашего if / else блока выше.