Страницы

Поиск по вопросам

воскресенье, 15 марта 2020 г.

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

#javascript #регулярные_выражения


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

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


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

UPD:

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


Ответы

Ответ 1



Могу предложить решение с match вместо split: "Казнить|, нельзя, помиловать.".match(/([^\|,]|\|.)+/g) # ["Казнить|, нельзя", " помиловать."]

Ответ 2



Давайте отталкиваться от того, что 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: Javascript: negative lookbehind equivalent? * How do you reverse a string in place in JavaScript?

Ответ 3



Вот вам такое уродство: "Казнить|, нельзя, по,мил|,овать.".replace(/([^\|])\,/g, '$1###').replace(/\|\,/g,',').split('###')

Ответ 4



Увидел что Вы отказались от регулярного выражения и решил предложить вариант, который, наверное, в тысячу раз быстрее будет - var text = "Казнить|, нельзя, помиловать."; function cut(text, search, ignore){ var startIndex = 0, endIndex = 0, result = []; while((endIndex = text.indexOf(search, endIndex)) > -1){ if(text.substring(endIndex, endIndex - 1) != ignore){ result.push(text.substring(startIndex, endIndex)); startIndex = endIndex; } endIndex++; } result.push(text.substring(startIndex, text.length)); return result; } console.log(cut(text, ',', '|')); // [ 'Казнить|, нельзя', ', помиловать.' ] var text = "Казнить|, нельзя, помиловать."; function cut(text, search, ignore){ var startIndex = 0, endIndex = 0, isNotComplete = true, isPush = false, result = []; while(isNotComplete){ isNotComplete = (endIndex = text.indexOf(search, endIndex)) > -1; if(isNotComplete && text.substring(endIndex, endIndex - 1) != ignore){ isPush = true; }else if(!isNotComplete){ isPush = true; endIndex = text.length; } if(isPush){ result.push(text.substring(startIndex, endIndex)); startIndex = endIndex; isPush = false; } endIndex++; } return result; } console.log(cut(text, ',', '|')); // [ 'Казнить|, нельзя', ', помиловать.' ]

Комментариев нет:

Отправить комментарий