Ниже приведены три способа ответить на вопрос без создания промежуточного массива. Все используют регулярное выражение:
R = /str|con|dex|wis|int|cha/
и возвращают следующее:
one_match? "It wasn't a con, really" #=> true
one_match? "That sounds to me like a wild guess." #=> falsy (nil or false)
one_match? "Both int and dex are present." #=> falsy (nil or false)
one_match? "Three is an integer." #=> true
one_match? "Both int and indexes are present." #=> falsy (nil or false)
# 1 Начало первого и последнего совпадения начинается с одного индекса?
def one_match?(s)
(idx = s.index(R)) && idx == s.rindex(R)
end
См. String # index и String # rindex .
# 2 Использовать форму String#index
, которая принимает аргументравен индексу, с которого начинается поиск.
def one_match?(s)
s.index(R) && s.index(R, Regexp.last_match.end(0)).nil?
end
См. Regexp :: last_match и MatchData # end . Regexp.last_match
можно заменить на $~
.
# 3. Использовать форму String # gsub , которая принимает один аргумент и не содержит блока, чтобы создать перечислитель, генерирующий совпадения
def one_match?(s)
s.gsub(/str|con|dex|wis|int|cha/).count { true } == 1
end
См. Перечислимый # count .
Совпадение только с целыми словами
В предпоследнем примере 'int'
соответствует 'int'
в 'integer'
и в последнем матче 'dex'
соответствует 'dex'
в 'indexes'
. Для обеспечения соответствия полных слов регулярное выражение можно изменить на:
/\b(?:str|con|dex|wis|int|cha)\b/