Java: Как разбить строку, игнорируя другие части - PullRequest
0 голосов
/ 13 июня 2019

У меня есть список строк, разделенных дефисом, например:

String s = "key-keyone-keytwo";

Когда я использую s.split("-"), я получаю массив как [key, keyone, keytwo], как и следовало ожидать. Где моя проблема возникает, когда у меня есть ключ, который содержит тире. Я решил, что буду избегать дефис-ключа так, чтобы:

String s1 = "key-key'-'one-keytwo";

Когда я разделяю строку s1 дефисом, мой результат должен быть [key, key-one, keytwo].

Что бы я положил в качестве регулярного выражения для разделения, чтобы оно соответствовало вышеуказанным критериям. Я не слишком знаком с шаблонами регулярных выражений, поэтому объяснение тоже было бы потрясающим.

Обновление : Слово «ключ» не будет жестко закодировано. Это может быть любая строка. В идеале, я бы хотел что-то вроде "someString->anotherString->another", где я мог бы разделить стрелку ->, как Java-лямбда. И если по какой-либо причине в ключевой строке содержится стрелка , ее можно экранировать как: "some'->'string->anotherString->another" и она превратится в: [some->string, anotherString, another] Я знаю, что это немного сложно, но любые предложения помогут!

Ответы [ 2 ]

1 голос
/ 13 июня 2019

Вы хотите разделить на -, но не на '-', но в то же время хотите заменить '-' на -. Вы не можете сделать это с помощью всего лишь вызова split(), поскольку он не выполняет замену.

Вы можете выполнить разделение, разделив на -, которому не предшествует или , за которым следует ':

s.split("(?<!')-|-(?!')")

Тест

public static void main(String[] args) {
    test("key-keyone-keytwo");
    test("key-key-'one-keytwo");
    test("key-key'-one-keytwo");
    test("key-key'-'one-keytwo");
}
private static void test(String str) {
    String[] split = str.split("(?<!')-|-(?!')");
    System.out.println(Arrays.toString(split));
}

выход

[key, keyone, keytwo]
[key, key, 'one, keytwo]
[key, key', one, keytwo]
[key, key'-'one, keytwo]

Как вы можете видеть, он не разделился на '-', но результат все еще имеет этот "побег", поэтому вам нужно выполнить исправление, чтобы это исправить:

String[] split = str.split("(?<!')-|-(?!')");
for (int i = 0; i < split.length; i++)
    split[i] = split[i].replaceAll("'-'", "-");

выход

[key, keyone, keytwo]
[key, key, 'one, keytwo]
[key, key', one, keytwo]
[key, key-one, keytwo]

Вы можете сделать это в одном выражении, используя Streams:

String[] split = Pattern.compile("(?<!')-|-(?!')")
        .splitAsStream(str)
        .map(s -> s.replaceAll("'-'", "-"))
        .toArray(String[]::new);

Что, конечно, тоже можно записать в одну строку:

String[] split = Pattern.compile("(?<!')-|-(?!')").splitAsStream(str).map(s -> s.replaceAll("'-'", "-")).toArray(String[]::new);
0 голосов
/ 13 июня 2019

Пожалуйста, обратитесь к ответам, связанным с Python, Java должна иметь аналогичные возможности - Разделение строки Python без разделения экранированного символа

>>> re.split(r'(?<!\')-', "key-key'-'one-keytwo")
  ['key', "key'-'one", 'keytwo']

Но '-' не идеальный способ избежатьразделители, вы можете использовать обратную косую черту

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...