我正在努力支持 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
方法,而不是使用 String
的 replaceFirst
的 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("&&", "&");
return result;
}
关于java - 在 Java 中使用字符串替换方法时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64993614/