#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)
Комментарии:
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
блока выше.