Вы можете сделать это с негативным взглядом. Вот несколько упрощенная задача для иллюстрации идеи:
String text = "a;b;c;d;<x;y;z>;e;f;g;<p;q;r;s>;h;i;j";
String[] parts = text.split(";(?![^<>]*>)");
System.out.println(java.util.Arrays.toString(parts));
// _ _ _ _ _______ _ _ _ _________ _ _ _
// [a, b, c, d, <x;y;z>, e, f, g, <p;q;r;s>, h, i, j]
Обратите внимание, что вместо ,
в качестве разделителя теперь используется ;
, а вместо "(
и ")
круглые скобки просто <
и >
, но идея по-прежнему работает.
По шаблону
[…]
- это класс символов . Нечто вроде [aeiou]
соответствует одному из строчных гласных. [^…]
является отрицательным классом символов. [^aeiou]
соответствует одному из всего, кроме строчных гласных.
Спецификатор повторения *
может использоваться для соответствия «нулю или более раз» предыдущего шаблона.
(?!…)
- негативный взгляд; он может использоваться для подтверждения того, что определенный шаблон НЕ совпадает, глядя вперед (т.е. вправо) текущей позиции.
Шаблон [^<>]*>
соответствует последовательности (возможно, пустой) всего, кроме скобок, после чего следует парантез закрывающего типа.
Собрав все вышеперечисленное вместе, мы получим ;(?![^<>]*>)
, что соответствует ;
, но только если мы не сможем увидеть закрывающую скобку в качестве первой скобки справа от нее, потому что свидетельство такого явления будет означать только то, что ;
находится внутри скобок.
Эта техника с некоторыми изменениями может быть адаптирована к исходной задаче. Не забудьте экранировать метасимволы регулярных выражений (
и )
, если необходимо, и, конечно, "
, а также \
в строковом литерале Java должны быть экранированы с помощью предшествующего \
.
Вы также можете использовать *
для улучшения производительности, т. Е. ;(?![^<>]*+>)
.
Ссылки