ReplaceFirst , Почему нельзя заменить специальные символы?

replaceFirst , Почему нельзя заменить специальные символы?

System.out.println(cal); // 1 * 1 + 1 <==== ???

package com;

import org.apache.commons.lang.StringUtils;

public class Test {

    public static void main(String[] args) {

        String cal = "[aaa] * [aaa] + [bbb]";

        int cnt = StringUtils.countMatches(cal, "[");

        String delStr = "";

        for (int i = 0; i < cnt; i++) {
            delStr = cal.substring(cal.indexOf("["), cal.indexOf("]") + 1);
            cal = cal.replaceFirst("["+delStr +"]", "1");
        }

        System.out.println(cal); // 1 * 1 + 1 <==== ???
    }
}

Вы должны попытаться рассказать нам, что должен делать код, [] — это специальные символы в регулярных выражениях, и их нужно экранировать, проверьте регулярное выражение по адресу: w3schools.com/java/java_regex.asp

Teddy Tsai 21.11.2022 13:04
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Как включить TLS в gRPC-клиенте и сервере : 2
Как включить TLS в gRPC-клиенте и сервере : 2
Здравствуйте! 🙏🏻 Надеюсь, у вас все хорошо и добро пожаловать в мой блог.
Сортировка hashmap по значениям
Сортировка hashmap по значениям
На Leetcode я решал задачу с хэшмапой и подумал, что мне нужно отсортировать хэшмапу по значениям.
Принципы SOLID - лучшие практики
Принципы SOLID - лучшие практики
SOLID - это аббревиатура, обозначающая пять ключевых принципов проектирования: принцип единой ответственности, принцип "открыто-закрыто", принцип...
gRPC на Android с использованием TLS
gRPC на Android с использованием TLS
gRPC - это относительно новая концепция взаимодействия между клиентом и сервером, но не более.
2
1
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Специальные символы, которые используются в регулярных выражениях, необходимо либо экранировать с помощью \, либо все выражение следует рассматривать как строковый литерал с помощью Pattern.quote, который в основном окружает регулярное выражение парой \Q и \E.

Кроме того, в представленном коде delStr будет включать пару квадратных скобок, поэтому замена должна происходить для регулярного выражения [[aaa]], а неожиданное совпадение — первое a в первом вхождении [aaa] — будет найдено и заменено для такого шаблона вместо подразумеваемая замена. Затем для следующих итераций cal выглядит как [1aa] * [aaa] + [bbb] и cal.indexOf("[") несколько раз приводит к одному и тому же первому вхождению.

Итак, следующее экранирование спецсимволов, описанное выше, отлично работает:

String delStr = "";

for (int i = 0; i < cnt; i++) {
    delStr = cal.substring(cal.indexOf("["), cal.indexOf("]") + 1);

    cal = cal.replaceFirst("\\Q" + delStr + "\\E", "1"); // literal mode
    // or cal = cal.replaceFirst(Pattern.quote(delStr), "1");
}

Кроме того, это решение может быть переработано, чтобы полностью избавиться от цикла и методов String::indexOf / String::replaceFirst, потому что подразумеваемый результат означает, что все подстроки между [ и ], включая скобки, должны быть заменены на 1, то есть String::replaceAll будет выполнять всю работу. работа:

cal = cal.replaceAll("\\[[^]]*\\]", "1"); // 1 * 1 + 1

Спасибо. Благодаря вам это улажено. String cal = "[aaa] * [aaa] + [bbb]"; int cnt = StringUtils.countMatches(cal, "["); Строка delStr = ""; for (int i = 0; i < cnt; i++) { delStr = StringUtils.substringBetween (cal, "[", "]"); cal = cal.replaceFirst("\[" + delStr + "\]", "1"); } System.out.println(cal); // 1 * 1 + 1

ych1215 22.11.2022 02:43

Другие вопросы по теме