Проблемы при работе с методом замены строк в java

#java

#java

Вопрос:

Я работаю над поддержкой уведомлений на устройстве Kindle. Мы получаем выражение sting с сервера, которое содержит темы (темы будут в одинарных кавычках). Нам нужно проверить, подписано ли устройство на topic. Если он подписан, то нам нужно заменить тему в логическом выражении на ‘1’, иначе на ‘0’. Ниже приведен пример того, как выглядит логическое выражение.

 ('18' in topics || '4' in topics) amp;amp; ('REG_92779' in topics amp;amp; 'REG_91212' in topics)
 

предположим, что устройство подписано на разделы ’18’, ‘4’ и не подписано на ‘REG_92779’
и ‘REG_91212’. Выражение должно стать

 ('1' || '1') amp;amp; ('0' amp;amp; '0')
 

После этого нам нужно удалить пробелы и кавычки. Выражение должно стать

 (1||1)amp;amp;(0amp;0)
 

Ниже приведен код

 private boolean checkNotificationValid(String leString) {
        // Remove the 'in topics' string. examples of logical expression as below
        // ('4' in topics amp;amp; '50000' in topics) || ('60' in topics || '3' in topics)
        // ('4' in topics amp;amp; ('50000' in topics || '60' in topics))
        leString = leString.replaceAll("in topics", "");
        Log.d(TAG, "Notifications : ADM : LE : Logical Expression received : "   leString);
        boolean result = false;

        // Find the topics in the logical expression and check whether the device is subscribed to
        // the topic. If device is subscribed to the topic, replace the topic with 1 or replace the
        // topic with 0. Below is the example.
        // Assume device is subscribed to topics 3 and 4.
        // Expression : ('4' amp;amp; '50000') || ('60' || '3')
        // After this block of code, it becomes : ('1' amp;amp; '0') || ('0' || '1')
        Pattern p = Pattern.compile("'(.*?)'");
        Matcher m = p.matcher(leString);
        while(m.find()) {
            Log.d(TAG, "Notifications : ADM : LE : "   m.group(1));

            // Check whether the device is subscribed to the topic
            if(NotificationUtils.isTopicExistInSharedPref(m.group(1))) {
                leString = leString.replaceFirst(m.group(1), "1");
            } else {
                leString = leString.replaceFirst(m.group(1), "0");
            }
        }

        // Remove the quotes and spaces from the string, replace '||' with '|', replace 'amp;amp;' with 'amp;'
        // ('1' amp;amp; '0') || ('0' || '1') -> (1amp;0)|(0|1)
        leString = leString.replaceAll("[' ]", "");
        leString = leString.replaceAll("\|\|", "|");
        leString = leString.replaceAll("amp;amp;", "amp;");

        return resu<
    }
 

Код работает нормально. Но если темы ‘1’ или ‘0’, это сбой. Ниже приведен пример,

 ('18' in topics || '4' in topics) amp;amp; ('1' in topics amp;amp; '1' in topics)
 

после проверки первых 2 разделов (18 и 4) строка становится

 ('1' || '1') amp;amp; ('1' amp;amp; '1')
 

Теперь для темы ‘1’, когда я пытаюсь заменить на 0 (поскольку устройство не подписано), оно заменяет первое ‘1’ там, где оно должно заменить 3-е ‘1’. Это становится, как показано ниже.

 ('0' || '1') amp;amp; ('1' amp;amp; '1')
 

это должно стать

 ('1' || '1') amp;amp; ('0' amp;amp; '1')
 

Такая же проблема возникает и с темой ‘0’.

Это происходит потому, что я использовал метод replaceFirst() . Если бы я попытался использовать replace(), он заменяет все вхождения в строку вместо замены конкретной темы. Может кто-нибудь, пожалуйста, помогите мне, как исправить эту проблему.

ПРИМЕЧАНИЕ: сначала я заменил на 1 или 0 в зависимости от подписки на устройство, а затем удалил кавычки (‘4’ -> ‘1’ -> 1) поскольку я не мог понять, как заменить тему цитатой на 1 или 0 (‘4’ -> 1).

Ответ №1:

Вместо использования replaceFirst of String вы можете использовать StringBuffer и метод добавления и замены appendReplacement Matcher .

Ваш код станет:

 private boolean checkNotificationValid(String leString) {
    leString = leString.replaceAll("in topics", "");
    Log.d(TAG, "Notifications : ADM : LE : Logical Expression received : "   leString);
    boolean result = false;

    StringBuffer buffer = new StringBuffer();
    Pattern p = Pattern.compile("'(.*?)'");
    Matcher m = p.matcher(leString);
    while(m.find()) {
        Log.d(TAG, "Notifications : ADM : LE : "   m.group(1));

        if(NotificationUtils.isTopicExistInSharedPref(m.group(1))) {
            m.appendReplacement(buffer, "1");
        } else {
            m.appendReplacement(buffer, "0");
        }
    }

    m.appendTail(buffer);
    String finalStr = buffer.toString();
    finalStr = finalStr.replaceAll("[' ]", "");
    finalStr = finalStr.replaceAll("\|\|", "|");
    finalStr = finalStr.replaceAll("amp;amp;", "amp;");

    return resu<
}