java - 在 java 中使用字符串替换方法时面临的问题
问题描述
我正在努力支持 Kindle 设备上的通知。我们从服务器接收到包含主题的表达式 sting(主题将用单引号括起来)。我们需要检查设备是否订阅了主题。如果已订阅,则需要将逻辑表达式中的主题替换为“1”,否则替换为“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)。
解决方案
代替使用replaceFirst
of String
,您可以使用StringBuffer
和追加替换appendReplacement
方法 of 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;
}
推荐阅读
- ruby-on-rails - 比较来自两个查询的值并在 Ruby 中返回匹配值
- flutter - 如何在 Dart 中获取 Annotation 元数据?
- agens-graph - 重新登录后无法访问图表
- javascript - 编辑承诺结果 (JavaScript)
- python - 从文本文件中检查 URL 文件是否存在
- ios - WKWebView 未在 URL 中打开带有梵文字体的 URL
- javascript - 使用 nextjs/react 访问 newsapi 时出现“TypeError:data.map 不是函数”
- google-sheets - 我需要相应的值自动出现在 Google 表格中
- reactjs - 如何导出命名空间中的打字稿接口以在另一个模块中使用?
- php - 没有写入php文件