Как отформатировать и заменить группы с помощью RegEx (или, может быть, нет?) (Java)
output = output.replaceAll("%(\\w+)%",getVar("$1"));
public String getVar(name){...return formatted;}
У меня есть эта строка кода (в JAVA), и функция под названием getVar()
это даст мне значение переменной с именем, которое мы хотим. Функция работает отлично, но этот код, похоже, больше не ищет группы.
Строка, которую я форматирую с помощью этого регулярного выражения:
"My name is %name% and I am %age% years old."
И вместо того, чтобы вернуть меня "My name is Paulo and I am 15 years old."
(Так как name = Paulo
а также age = 15
) Это ничего мне не возвращает. Вместо замены регулярного выражения на getVar(name)
или же getVar(age)
, он заменяет его getVar("$1")
,
Есть ли какой-то способ исправить это, это ошибка или предполагаемое поведение? И если это так, как я могу получить тот же результат другим способом?
РЕДАКТИРОВАТЬ:
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));
}
Работает ли для этого конкретного случая... Но все же, есть ли способ использовать функции внутри replaceAll()
и поддержание групп (например, $1
, $2
) работает внутри функции?
РЕДАКТИРОВАТЬ 2:
//Variables//
ArrayList<String> varnames = new ArrayList<String>(0);
ArrayList<String> varvalues = new ArrayList<String>(0);
//end of Variables
private String getVar(String name){
String returnv = "";
if(varnames.contains(name.toLowerCase())) returnv = varvalues.get(varnames.indexOf(name.toLowerCase()));
//System.out.println("\n\n"+name+"\n\n");
return returnv;
}
private String format(String input){
String output = input;
output = output.replace("[br]","/n");
for(String i: varnames){
output = output.replaceAll("%"+i+"%",getVar(i));//This is how I am parsing the variables.
}
//Here I want to handle inline functions... for example: a function called 'invert' that would switch the letters. If the input String that is being formatted (output) contains the regex, the function needs to evaluate and replace.
//How I tried to do it:
output.replaceAll("invert\((\w+)\)",invertLetters("$1"));
return output;
}
public String invertLetters(String input){//Inverts the letters of the String}
1 ответ
Как уже упоминалось, codisfy не совсем понятно, если вы говорите о java
или же javascript
, как вы используете replaceAll
метод я буду считать, что вы используете java
, Однако то, что я объясню ниже, действительно для большинства (если не для всех) систем регулярных выражений независимо от языка программирования.
Когда вы звоните outputString=inputString.replaceAll("REGEX","REPLACEMENT");
метод replaceAll
настроит свой внутренний движок регулярных выражений, построит конечный автомат (для простоты, давайте опустим разницу между DFA
/ NFA
здесь) с регулярным выражением, переданным в качестве параметра и проанализировать inputString
на котором он вызывается для того, чтобы сделать замену и вернуть результат (outputString
).
Когда метод вызывается, он также нуждается в замене String
(REPLACEMENT
) это обычная строка, которая может содержать или не содержать обратных ссылок на некоторые группы, чтобы включить некоторую контекстную замену (используя синтаксис $1
, $2
или же \1
, \2
... в зависимости от языка).
Что очень важно понять, это то, что и регулярное выражение, и его замещающая строка являются простыми строками, не имеющими особого значения вне механизма регулярных выражений (метод replaceAll
).
Следовательно, если вы повторно используете их в других методах (например, передавая их в качестве параметров), они будут интерпретироваться literally
как и в случае с другими обычными строками.
Так что не ожидайте, что $1
заменяется name
или же age
в вашем звонке getVar("$1")
, Это будет просто $1
и ничего больше.
Кроме того, как говорится, ваш метод public void getVar(name){...}
даже не возвращает строку, так как ее тип возврата void
, как следствие, если вы код в java
и если вы используете replaceAll
метод класса String (который ожидает 2 строки в качестве аргументов), он даже НЕ будет компилироваться в первую очередь.
Я позволю вам реализовать остальную часть кода, но если вы измените цикл замены следующим образом, он должен работать:
String input="My name is %name% and I am %age% years old.";
Matcher matcher = Pattern.compile("%(\\w+)%").matcher(input);
String output=new String(input);
while (matcher.find()) {
System.out.println("------------------------------------");
System.out.println("Back reference:" + matcher.group(1));
String group=matcher.group(1);//give access to the first matching group so that it can be reused
output=output.replaceAll("%"+group+"%", getVar(group));
}
System.out.println(output);
getVar
код метода: (я позволю вам адаптировать его)
public static String getVar(String name){
if(name.equals("name"))
return "Paulo";
return "15";
}
ВЫХОД:
------------------------------------
Back reference:name
------------------------------------
Back reference:age
My name is Paulo and I am 15 years old.