Сплит 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$
Другие вопросы по тегам