Я застрял, пытаясь придумать регулярное выражение, чтобы разбить строки со следующими свойствами:
- С разделителями | (труба) символ
- Если отдельное значение содержит канал, экранированный \ (обратная косая черта)
- Если отдельное значение заканчивается обратной косой чертой, экранируется обратной косой чертой
Так, например, вот несколько строк, которые я хочу разбить:
One|Two|Three
должен дать: ["One", "Two", "Three"]
One\|Two\|Three
должен дать: ["One|Two|Three"]
One\\|Two\|Three
должен дать: ["One\", "Two|Three"]
Теперь, как я мог бы разделить это с помощью одного регулярного выражения?
ОБНОВЛЕНИЕ: Как многие из вас уже предположили, это не очень хорошее применение регулярных выражений. Кроме того, решение регулярных выражений на несколько порядков медленнее, чем просто перебор символов. В итоге я перебрал символы:
public static List<String> splitValues(String val) {
final List<String> list = new ArrayList<String>();
boolean esc = false;
final StringBuilder sb = new StringBuilder(1024);
final CharacterIterator it = new StringCharacterIterator(val);
for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
if(esc) {
sb.append(c);
esc = false;
} else if(c == '\\') {
esc = true;
} else if(c == '|') {
list.add(sb.toString());
sb.delete(0, sb.length());
} else {
sb.append(c);
}
}
if(sb.length() > 0) {
list.add(sb.toString());
}
return list;
}