Сплит Java пожирает моих персонажей
У меня есть такая строка String str = "la$le\\$li$lo"
,
Я хочу разделить его, чтобы получить следующий вывод "la","le\\$li","lo"
, \$ - это экранированный $, поэтому его следует оставить в выходных данных.
Но, когда я делаю str.split("[^\\\\]\\$")
ты получаешь "l","le\\$l","lo"
,
Из того, что я получаю, мое регулярное выражение сопоставляет $ и i $ и затем удаляет. Есть идеи, как вернуть моих персонажей?
Спасибо
4 ответа
Используйте сопоставления с нулевой шириной:
String str = "la$le\\$li$lo";
System.out.println(java.util.Arrays.toString(
str.split("(?<!\\\\)\\$")
)); // prints "[la, le\$li, lo]"
Регулярное выражение по существу
(?<!\\)\$
Он использует отрицательный взгляд назад, чтобы утверждать, что нет предшествующего \
,
Смотрите также
Больше примеров разбиения на утверждения
Простое разбиение предложения с сохранением знаков препинания:
String str = "Really?Wow!This.Is.Awesome!";
System.out.println(java.util.Arrays.toString(
str.split("(?<=[.!?])")
)); // prints "[Really?, Wow!, This., Is., Awesome!]"
Разбиение длинной строки на части фиксированной длины, используя \G
String str = "012345678901234567890";
System.out.println(java.util.Arrays.toString(
str.split("(?<=\\G.{4})")
)); // prints "[0123, 4567, 8901, 2345, 6789, 0]"
Использование комбо lookbehind/lookahead:
String str = "HelloThereHowAreYou";
System.out.println(java.util.Arrays.toString(
str.split("(?<=[a-z])(?=[A-Z])")
)); // prints "[Hello, There, How, Are, You]"
Смежные вопросы
Причина удаления $ и i$ в том, что регулярное выражение [^\\]\$
соответствует любому символу, который не '\', за которым следует '$'. Вы должны использовать утверждения нулевой ширины
Это та же самая проблема, с которой люди пытаются найти q, а не u.
Первый разрез по правильному регулярному выражению /(?<!\\)\$/
("(?<!\\\\)\\$"
в яве)
class Test {
public static void main(String[] args) {
String regexp = "(?<!\\\\)\\$";
System.out.println( java.util.Arrays.toString( "1a$1e\\$li$lo".split(regexp) ) );
}
}
Урожайность:[1a, 1e\$li, lo]
Вы можете сначала попытаться заменить "\$" другой строкой, такой как кодировка URL для $ ("%24"), а затем разделить:
String splits[] = str.replace("\$","%24").split("[^\\\\]\\$");
for(String str : splits){
str = str.replace("%24","\$");
}
В более общем случае, если st r строится чем-то вроде
str = a + "$" + b + "$" + c
Затем вы можете URLEncode a, b и c, прежде чем добавлять их вместе
import java.net.URLEncoder.encode;
...
str = encode(a) + "$" + encode(b) + "$" + encode(c)
import java.util.regex.*;
public class Test {
public static void main(String... args) {
String str = "la$le\\$li$lo";
Pattern p = Pattern.compile("(.+?)([^\\\\]\\$)");
Matcher m = p.matcher(str);
while (m.find()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
}
}
}
дает
l
a$
le\$l
i$