#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<
}