Так что это решение, которое мне сейчас нравится:
class String
def get_column(n)
self =~ /\A\{(?:\w*\|){#{n}}(\w*)(?:\|\w*)*\}\Z/ && $1
end
end
Мы используем регулярное выражение, чтобы убедиться, что строка имеет правильный формат, и одновременно захватывает правильный столбец.
Объяснение регулярного выражения:
\A
- начало строки, а \Z
- конец, поэтому это регулярное выражение соответствует строке ввода.
- Поскольку фигурные скобки имеют особое значение, мы избегаем их как
\{
и \}
, чтобы соответствовать фигурным скобкам в начале и конце строки.
- далее, мы хотим пропустить первые n столбцов - нас это не волнует.
- Предыдущий столбец - это некоторое количество букв, за которыми следует вертикальная черта, поэтому мы используем стандартный
\w
для сопоставления со словом-подобным символом (включает цифры и подчеркивание, но почему бы и нет) и *
для сопоставления с любым числом из них. Вертикальная черта имеет особое значение, поэтому мы должны экранировать ее как \|
. Так как мы хотим сгруппировать это, мы заключаем все это в неотмечающие паренсы (?:\w*\|)
(?:
делает их не захватывающими).
- Теперь у нас есть
n
из предыдущих столбцов, поэтому мы указываем регулярное выражение для сопоставления с шаблоном столбца n
раз, используя регулярное выражение count - просто поместите число в фигурные скобки после шаблона. Мы используем стандартную строковую подстановку, поэтому мы просто вводим {#{n}}
, что означает «соответствовать предыдущему шаблону ровно n
раз.
- первый столбец без пропусков - тот, о котором мы заботимся, поэтому мы помещаем его в список парней:
(\w*)
- тогда мы пропускаем остальные столбцы, если таковые существуют:
(?:\|\w*)*
.
Захват столбца переводит его в $1
, поэтому мы возвращаем это значение, если регулярное выражение соответствует. Если нет, мы возвращаем ноль, так как эта строка не имеет n
-го столбца.
В общем, если вы хотите, чтобы в ваших столбцах было больше, чем просто слова (например, "{a phrase or two|don't forget about punctuation!|maybe some longer strings that have\na newline or two?}"
), просто замените все \w
в регулярном выражении на [^|{}]
, чтобы в каждом столбце содержалось что угодно, кроме фигурная скобка или вертикальная черта.
Вот мое предыдущее решение
class String
def get_column(n)
raise "not a column string" unless self =~ /\A\{\w*(?:\|\w*)*\}\Z/
self[1 .. -2].split('|')[n]
end
end
Мы используем похожее регулярное выражение, чтобы убедиться, что строка содержит набор столбцов или выдает ошибку. Затем мы удаляем фигурные скобки спереди и сзади (используя self[1 .. -2]
, чтобы ограничить подстроку, начинающуюся с первого символа и заканчивающуюся рядом с последним), разделяем столбцы с помощью символа канала (используя .split('|')
, чтобы создать массив столбцов), а затем найдите n-й столбец (используя стандартный поиск Array с [n]
).
Я просто подумал, что пока я использую регулярное выражение для проверки строки, я мог бы также использовать его для захвата столбца.