Ответ 1
Вы используете replaceAll()
, который принимает регулярное выражение. В regex-land, .
означает "любой символ". Вместо этого используйте replace()
, который работает с буквальными строками.
У меня действительно странная ошибка в моем java-коде и не могу понять, что не так.
Скажем, у меня есть этот код:
private void test()
{
String test1 = replace("1.25");
String test2 = replace("1.5");
String test3 = replace("1.75");
}
private String replace(String s)
{
s = s.replaceAll(".25", "¼");
s = s.replaceAll(".5", "½");
s = s.replaceAll(".75", "¾");
return s;
}
Тогда результат будет:
test1 = "¼"
test2 = "½"
test3 = "½" ??????????
Может кто-нибудь объяснить, почему test3 становится "½" ?
Вы используете replaceAll()
, который принимает регулярное выражение. В regex-land, .
означает "любой символ". Вместо этого используйте replace()
, который работает с буквальными строками.
Потому что replaceAll
принимает регулярное выражение. Это означает, что .
интерпретируется как подстановочный знак, который также соответствует 7
, так что .5
соответствует 75
. Вы можете убежать в регулярных выражениях с помощью \
, но обратите внимание, что это также строка, которая означает, что вам придется дважды бежать: так replaceAll("\\.5", "½")
будет делать то, что вы хотели.
Проблема заключается в том, что в регулярном выражении .
означает любой символ. replaceAll
принимает регулярное выражение в качестве параметра, поэтому вы должны использовать другие средства, такие как replace
.
Функция replace all интерпретирует первый аргумент как регулярное выражение. ".5" в качестве регулярного выражения будет соответствовать любому, за которым следует 5, например, вашей тестовой строке2. Побег '.' символ с обратной косой чертой:
s = s.replaceAll("\\.25", "¼");
replaceAll
использует regex в качестве первого параметра, который нужно будет найти, а точка .
в регулярном выражении является метасимволом, который будет соответствовать всем символам, кроме новой строки. Поэтому, когда вы используете
s = s.replaceAll(".5", "½");
on "1.75"
.5
может соответствовать 75
(поскольку .
соответствует всем). Поэтому после такого изменения
1.75
-- will become
1.½
(заметим, что 1.25
работает корректно только потому, что вы использовали .25
до .5
)
Чтобы предотвратить такое поведение, вам нужно избежать точки. Вы можете сделать это с помощью
\
перед ним (помните, что для создания литерала \
вам нужно записать его как "\\"
) "\\."
,[.]
,\Q
и \E
, которые представляют начало и конец цитаты \\Q.\\E
\Q
и \E
также можно выполнить с помощью Pattern.quote(".")
Pattern.LITERAL
, чтобы сделать все метасимволы, используемые в литералах шаблонов.Если вы хотите, чтобы весь наш шаблон был простым литералом, вы можете использовать replace
вместо replaceAll
, который будет автоматически использовать флаг Pattern.LITERAL
и изменить все метасимволы регулярных выражений на простые литералы.
Итак, вы можете попробовать что-то вроде
return s.replaceAll("\\.25", "¼").replaceAll("\\.5", "½").replaceAll("\\.75", "¾");
или более простой
return s.replace(".25", "¼").replace(".5", "½").replace(".75", "¾");
Первым параметром replaceAll() является REGEX, а .. означает любой символ в области REGEX.
Используйте String.replace()
вместо String.replaceAll()
Сделайте это как
private String replace(String s)
{
s = s.replace(".25", "¼");
s = s.replace(".5", "½");
s = s.replace(".75", "¾");
return s;
}