Регулярное выражение для разделения по запятым, кроме экранированных

Рейтинг: 3Ответов: 1Опубликовано: 21.04.2015

Дано: Строка, например, вида такого: "Казнить|, нельзя, помиловать.".
Задача: Разделить строку по запятым, но там, где | (вроде экранирования), запятую нужно игнорировать.
Т.е. должно вернуть это:

["Казнить|, нельзя", " помиловать."]

Возможно просмотр назад дал бы пользу, но в JS, где мне это нужно сделать, такой фичи нет.
Максимум что добился - это деление по запятой (/([^,]+)/g, это было легко), без учёта | (а тут забуксовал) и головная боль.
Заранее благодарен за любую помощь!

UPD:

По большому счёту не важно что будет номинально считаться экранированием запятой - обратный слэш, пайп или квадратик из ASCII-арта, но некто в ответах упёрся бараном в новые ворота на свойства экранирования \, поэтому теперь экранирует пайп.

Ответы

▲ 1

Давайте отталкиваться от того, что javascript поддерживает негативный просмотр вперед.
Тогда последовательность действий такова:

  • Развернуть исходную строку
  • Разбить полученную строку с помощью следующего регулярного выражения:
    /,(?![|])/
  • Развернуть каждый элемент полученного массива совпадений и сам массив совпадений, чтобы получить искомый результат

Вот код:

// (!!!) Будьте осторожны, используя эту функцию *
var naiveReverse = function(string) {
    return string.split('').reverse().join('');
}

var string = "Казнить|, нельзя, помиловать.";

var reversed_array = naiveReverse(string).split(/,(?![|])/);

var result_array = reversed_array.map(function(item) {
    return naiveReverse(item);
}).reverse();

Результат:

["Казнить|, нельзя", " помиловать."]  

Составлено на основе ответов к этим вопросам на StackOverflow: