Java String Split с использованием Regex с Escape-символом - PullRequest
1 голос
/ 21 марта 2019

У меня есть строка, которую нужно разделить на основе разделителя (:).Этот разделитель может быть экранирован символом (например, «?»).В основном разделителю может предшествовать любое количество escape-символов.Ниже приведен пример строки:

a:b?:c??:d???????:e

Здесь, после разделения, он должен дать следующий список строк:

a 
b?:c?? 
d???????:e

В основном, если разделителю (:) предшествует четноеколичество escape-символов, оно должно быть разделено.Если ему предшествует нечетное количество escape-символов, он не должен разделяться.Есть ли решение этого с помощью регулярных выражений?Любая помощь будет принята с благодарностью.

Подобный вопрос был задан ранее здесь , но ответы не работают для этого варианта использования.

Обновление: решение с регулярным выражением: (?: \?. | [^ :?]) * правильно разделить строку.Тем не менее, это также дает несколько пустых строк.Если вместо * задано +, даже реальные пустые совпадения также игнорируются.(Например: - a :: b дает только a, b)

1 Ответ

2 голосов
/ 21 марта 2019

Сценарий 1: пустых совпадений нет

Вы можете использовать

(?:\?.|[^:?])+

Или, следуя шаблону в связанном ответе

(?:\?.|[^:?]++)+

См. это демонстрационное регулярное выражение

Подробно

  • (?: - начало группы без захвата
    • \?. - ? (разделитель), за которым следует любой символ
    • | - или
    • [^:?] - любой символ, кроме : (ваш символ разделителя) и? (escape-символ)
  • )+ - 1 или более повторений.

На Java:

String regex = "(?:\\?.|[^:?]++)+";

Если входные данные содержат разрывы строк, добавьте шаблон с (?s) (например, (?s)(?:\\?.|[^:?])+) или скомпилируйте шаблон с флагом Pattern.DOTALL.

Сценарий 2: Включены пустые соответствия

Вы можете добавить (?<=:)(?=:) альтернативу вышеуказанному шаблону, чтобы сопоставить пустые строки между : символами, см. это демонстрационное выражение регулярного выражения :

String s = "::a:b?:c??::d???????:e::";
Pattern pattern = Pattern.compile("(?>\\?.|[^:?])+|(?<=:)(?=:)");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println("'" + matcher.group() + "'"); 
} 

Вывод Java демо :

''
'a'
'b?:c??'
''
'd???????:e'
''

Примечание , что есливы также хотите сопоставить пустые строки в начале / конце строки, используйте (?<![^:])(?![^:]) вместо (?<=:)(?=:).

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