Сплит по последовательной группе в Ruby - PullRequest
0 голосов
/ 31 октября 2018

У меня есть следующая строка:

txt = "HwwwwjjaoHHHHaffgd"

Мне нужно сформировать массив, сгруппировав одинаковые последовательные символы, чтобы получить:

["H" "wwww" "jj" "a" "o" "HHHH" "a" "ff" "g" "d"]

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Давайте разберем принятый ответ:

str = "HwwwwjjaoHHHHaffgd"

str.scan(/((\w)\2*)/).map(&:first)

# => ["H", "wwww", "jj", "a", "o", "HHHH", "a", "ff", "g", "d"]

Как это работает?

.scan #from https://ruby-doc.org/core-2.2.0/String.html

#scan(pattern) 
#scan(pattern) {|match, ...| block } → str

Обе формы перебирают str в соответствии с шаблоном (который может быть Регулярное выражение или строка). Для каждого совпадения генерируется результат и либо добавляется в массив результатов или передается в блок. Если шаблон не содержит групп, каждый отдельный результат состоит из сопоставленных строка, $ &. Если шаблон содержит группы, каждый отдельный результат сам массив, содержащий одну запись на группу.

Используемое регулярное выражение

\w соответствует любому символу любого слова (буква, цифра, подчеркивание) (\w) оберните его в parens aka «группа захвата» - скобки сгруппируют регулярное выражение между ними. Они фиксируют текст, соответствующий регулярному выражению внутри них, в пронумерованную группу, которую можно повторно использовать с пронумерованной обратной ссылкой. Они позволяют применять операторы регулярных выражений ко всему сгруппированному регулярному выражению.

Это то, что вы делаете с (\w)\2, и передача его в .scan внутри // указывает сканированию, что это регулярное выражение, а не чистая строка.

str.scan(/((\w)\2*)/) # will return the following array of arrays
[ ["H", "H"], ["wwww", "w"], ["jj", "j"], ["a", "a"], ["o", "o"], 
  ["HHHH", "H"], ["a", "a"], ["ff", "f"], ["g", "g"], ["d", "d"] ]

Теперь вам нужен только 1-й элемент в каждом массиве, поэтому вы можете просто вызвать .map на результат

str.scan(/((\w)\2*)/).map(&:first) # shorthand for 
str.scan(/((\w)\2*)/).map{|i| i.first}

#=> ["H", "wwww", "jj", "a", "o", "HHHH", "a", "ff", "g", "d"]

Вот некоторые полезные ресурсы, которые вы могли бы использовать в будущем, когда вам понадобится обрабатывать регулярные выражения самостоятельно.

https://www.regular -expressions.info / tutorial.html

Это немного устарело, но часто полезно для быстрого тестирования http://rubular.com/

0 голосов
/ 01 ноября 2018

Вот несколько способов сделать это.

txt = "Hwwww||333jjao{{\\HHHH@@affg//d"

txt.split(/(?<=(.))(?!\1)/).each_slice(2).map(&:first)

txt.each_char.slice_when(&:!=).map(&:join)

txt.each_char.chunk(&:itself).map { |_,a| a.join }

txt.each_char.chunk_while(&:==).map(&:join)

txt.gsub(/(?<=(.))(?!\1)/, ' ').split

txt.gsub(/(.)\1*/).reduce([], &:<<)  

txt[1..-1].each_char.with_object([txt[0]]) {|c,a| a.last[-1]==c ? (a.last<<c) : a << c}

Все вышеприведенное возвращение

["H", "wwww", "||", "333", "jj", "a", "o", "{{", "\\", "HHHH", "@@", "a",
 "ff", "g", "//", "d"]
0 голосов
/ 31 октября 2018

На основании ответа @ iGian:

def split_by_chars
  scan(/((\w)\2*)/).map(&:first)
end

txt = "HwwwwjjaoHHH HHHaffgd"
txt.split_by_chars
# => ["H", "wwww", "jj", "a", "o", "HHH", "HHH", "a", "ff", "g", "d"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...