java - 在 Java 中使用字符串替换方法时遇到问题

标签 java

我正在努力支持 Kindle 设备上的通知。我们从包含主题的服务器接收到表达式 sting(主题将用单引号引起来)。我们需要检查设备是否订阅了主题。如果它被订阅了,那么我们需要将逻辑表达式中的主题替换为'1' else 替换为'0'。下面是逻辑表达式的示例。

('18' in topics || '4' in topics) && ('REG_92779' in topics && 'REG_91212' in topics)

假设设备订阅了主题“18”、“4”但未订阅“REG_92779” 和“REG_91212”。表达式应该变成

('1' || '1') && ('0' && '0')

之后我们需要删除空格和引号。表达式应该变成

(1||1)&&(0&0)

下面是代码

private boolean checkNotificationValid(String leString) {
        // Remove the 'in topics' string. examples of logical expression as below
        // ('4' in topics && '50000' in topics) || ('60' in topics || '3' in topics)
        // ('4' in topics && ('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' && '50000') || ('60' || '3')
        // After this block of code, it becomes : ('1' && '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 '&&' with '&'
        // ('1' && '0') || ('0' || '1') -> (1&0)|(0|1)
        leString = leString.replaceAll("[' ]", "");
        leString = leString.replaceAll("\\|\\|", "|");
        leString = leString.replaceAll("&&", "&");

        return result;
    }

代码运行良好。但如果主题为“1”或“0”,则失败。下面是示例,

('18' in topics || '4' in topics) && ('1' in topics && '1' in topics)

在前 2 个主题(18 和 4)验证后,字符串变为

('1' || '1') && ('1' && '1')

现在对于主题“1”,当我尝试用 0 替换时(因为设备未订阅),它会替换第一个“1”,它应该替换第三个“1”。如下图所示。

('0' || '1') && ('1' && '1')

应该变成

('1' || '1') && ('0' && '1')

同样的问题也发生在主题“0”上。

发生这种情况是因为我使用了 replaceFirst() 方法。如果我尝试使用 replace() ,它会替换字符串中所有出现的地方,而不是替换特定主题。谁能帮我解决这个问题。

注意:我首先根据设备订阅用 1 或 0 替换,后来我删除了引号 ('4' -> '1' -> 1),因为我不知道如何用 1 或 0 ('4' -> 1) 替换引号。

最佳答案

您可以使用 StringBuffer 和追加替换 appendReplacement 方法,而不是使用 StringreplaceFirstMatcher .

您的代码将变成:

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("&&", "&");

    return result;
}

关于java - 在 Java 中使用字符串替换方法时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64993614/

相关文章:

java - junit5如何运行测试文件夹中的所有类?

java - 无法解析芬兰语言环境中的日期

java - 如何将参数从 servlet 传递到 JavaScript

java - (JUNIT/Spring 3.2) 未找到线程绑定(bind)请求 : Are you referring to request attributes outside of an actual web request

java - Spring MVC - 将枚举填充到下拉列表

JavaFX:CellFactory/Cell 与单个节点

java - 错误:Error: Could not create the Java Virtual Machine

java - pdfBox 之后我无法删除文件

java - 如何在 android 中以编程方式添加或删除 intent 过滤器?

java - Mockito 错误 : "Wanted but not invoked:.. However, there were other interactions with this mock"