Как я могу использовать регулярные выражения в Ruby, чтобы разбить строку на массив слов, которые она содержит? - PullRequest
0 голосов
/ 01 июня 2018

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

  1. Он должен разбивать строку по всем тире, пробелам, подчеркиваниям и периодам.
  2. Когда несколько из вышеупомянутых символов отображаются вместе, он должен толькоразделить один раз (поэтому '-. quick' должен быть разделен на ['the', 'quick'], а не ['the', '', '', 'quick'])
  3. Должен быть разделенстрока с новыми заглавными буквами, при этом эта буква с соответствующим словом ('theQuickBrown' разделяется на ['', 'quick', 'brown']
  4. Она должна сгруппировать несколько заглавных букв в строке вместе('LETS_GO' должен быть разделен на ['let', 'go'], а не ['l', 'e', ​​'t', 's', 'g', 'o'])
  5. Он должен использовать только строчные буквы в массиве split.

Если он работает правильно, следующее должно быть верно

"theQuick--brown_fox JumpsOver___the.lazy  DOG".split_words == 
["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"]

До сих пор я был в состоянии получить почтитам, с единственной проблемой в том, что он разделяется на каждую заглавную, поэтому "DOG" .split_words это ["d", "o", "g"], а не ["dog"]

Я также используюкомбинация регулярных выражений и карт / филв разделенном массиве, чтобы найти решение, бонусные баллы, если вы можете сказать мне, как избавиться от этого и использовать только регулярное выражение.

Вот что у меня есть:

class String
  def split_words 
    split(/[_,\-, ,.]|(?=[A-Z]+)/).
    map(&:downcase).
    reject(&:empty?)
  end 
end

Который при вызове строки из вышеприведенного теста возвращает:

["the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "d", "o", "g"]

Как я могу обновить этот метод, чтобы он соответствовал всем вышеперечисленным спецификациям?

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Вы можете использовать соответствующий подход для извлечения кусков из 2 или более заглавных букв или букв, за которыми следуют только 0+ строчных букв:

s.scan(/\p{Lu}{2,}|\p{L}\p{Ll}*/).map(&:downcase)

См. Rubydemo и Rubular demo .

Соответствует регулярному выражению:

  • \p{Lu}{2,} - 2 или более заглавных букв
  • | - или
  • \p{L} - любая буква
  • \p{Ll}* - 0 или более строчных букв.

С map(&:downcase), предметы, которые вы получаетес .scan() переводятся в нижний регистр.

0 голосов
/ 01 июня 2018
r = /
    [- _.]+      # match one or more combinations of dashes, spaces,
                 # underscores and periods
    |            # or
    (?<=\p{Ll})  # match a lower case letter in a positive lookbehind
    (?=\p{Lu})   # match an upper case letter in a positive lookahead
    /x           # free-spacing regex definition mode

str = "theQuick--brown_dog, JumpsOver___the.--lazy   FOX for $5"

str.split(r).map(&:downcase)
  #=> ["the", "quick", "brown", "dog,", "jumps", "over", "the", "lazy",
       "fox", "for", "$5"]

Если строка должна быть разбита на пробелы и все знаки пунктуации, замените [- _.]+ на [ [:punct:]]+.Найдите "[[:punct:]]" в Regexp для справки.

0 голосов
/ 01 июня 2018

Вы можете слегка изменить регулярное выражение, чтобы оно не разбивалось на каждую заглавную букву, а на каждую последовательность букв, начинающуюся с заглавной.Это просто включает в себя [a-z]+ после [A-Z]+

string = "theQuick--brown_fox JumpsOver___the.lazy  DOG"
regex = /[_,\-, ,.]|(?=[A-Z]+[a-z]+)/
string.split(regex).reject(&:empty?)
# => ["the", "Quick", "brown", "fox", "Jumps", "Over", "the", "lazy", "DOG"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...