Разделить строку с несколькими разделителями в Ruby - PullRequest
11 голосов
/ 02 июня 2011

Например, у меня есть такая строка:

options = "Cake or pie, ice cream, or pudding"

Я хочу иметь возможность разбить строку с помощью or, , и , or.

Дело в том, что я смог это сделать, но только сначала проанализировав , и , or, а затем разделив каждый элемент массива на or, сгладив впоследствии результирующий массив как таковой:*

options = options.split(/(?:\s?or\s)*([^,]+)(?:,\s*)*/).reject(&:empty?);
options.each_index {|index| options[index] = options[index].sub("?","").split(" or "); }

Результирующий массив выглядит так: ["Cake", "pie", "ice cream", "pudding"]

Есть ли более эффективный (или более простой) способ разбить мою строку на эти три разделителя?

Ответы [ 3 ]

15 голосов
/ 02 июня 2011

А как насчет следующего:

options.gsub(/ or /i, ",").split(",").map(&:strip).reject(&:empty?)
  • заменяет все разделители, но ,
  • разделяет его на ,
  • обрезает каждый символпоскольку такие вещи, как ice cream с начальным пробелом, могут остаться
  • удаляет все пустые строки
9 голосов
/ 02 июня 2011

Прежде всего, ваш метод может быть немного упрощен с Array#flatten:

>> options.split(',').map{|x|x.split 'or'}.flatten.map(&:strip).reject(&:empty?)
=> ["Cake", "pie", "ice cream", "pudding"]

Я бы предпочел использовать одно регулярное выражение:

>> options.split /\s*, or\s+|\s*,\s*|\s+or\s+/
=> ["Cake", "pie", "ice cream", "pudding"]

Вы можете использовать | в регулярном выражении, чтобы указать альтернативы, а , or сначала гарантирует, что он не произведет пустой элемент. Захват пробелов с помощью регулярных выражений, вероятно, лучше всего подходит для эффективности, поскольку вам не нужно снова сканировать массив.

Как отмечает Забба, вы все еще можете отказаться от пустых элементов, предлагая следующее решение:

>> options.split(/,|\sor\s/).map(&:strip).reject(&:empty?)
=> ["Cake", "pie", "ice cream", "pudding"]
3 голосов
/ 02 июня 2011

Поскольку "or" и "," делают одно и то же, лучший подход состоит в том, чтобы указать регулярному выражению, что несколько случаев должны рассматриваться как один случай:

options = "Cake or pie, ice cream, or pudding"
regex = /(?:\s*(?:,|or)\s*)+/
options.split(regex)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...