Ruby - Найти положение совпадения REGEX и применить ли регулярное выражение в проигрышном матче? - PullRequest
1 голос
/ 22 марта 2011

У меня есть список из нескольких выражений REGEX

sample_text = 'lots of text'

regex_1 = / stuff 1 /
regex_2 = / different stuff 2 /
regex_3 = / different stuff 3 /
regex_4 = / different stuff 4 /
regex_5 = / different stuff 5 /

Что бы я хотел знать, как элегантно сделать это для каждого регулярного выражения, выполнить поиск в sample_text и вернуть позицию соответствия.

Затем я хочу использовать регулярное выражение, которое имеет самую низкую / самую близкую позицию совпадения от начала sample_text

Мысли? Предложения? Спасибо

Ответы [ 3 ]

2 голосов
/ 22 марта 2011
sample_text = 'lots of text'

regexes = [
  / stuff 1 /,
  / different stuff 2 /,
  / different stuff 3 /,
  / different stuff 4 /,
  / different stuff 5 /
]

infinity = 1.0/0
regex_to_use = regexes.min_by{ |re| sample_text.index(re) || infinity }

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

2 голосов
/ 22 марта 2011
regexes = [ regex_1, regex_2, regex_3, regex_4, regex_5 ].
  select{|r| sample_text =~ r }.
  sort_by{|r| sample_text =~ r}
regexes.first
#=> /some regex here/

Сортирует регулярные выражения по позициям совпадений.

  1. sample_text =~ r возвращает позицию совпадения
  2. sort_by отсортирует наш массив по позициям совпадения

UPD

Как только что упомянутый @Holger match может вернуть nil, что сломает нашу sort_by, поэтому нам следует select только те регулярные выражения, которые будутmatch наш smaple_text

и коротенький хакерский путь:

[ regex_1, regex_2, regex_3, regex_4, regex_5 ].sort_by{|r| 1.0/(sample_text=~r).to_i}
0 голосов
/ 22 марта 2011
sample_text = 'lots of text'

regexes = [
    / stuff 1 /,
    / different stuff 2 /,
    / different stuff 3 /,
    / different stuff 4 /,
    / different stuff 5 /
]

positions = regexes.map{|re| sample_text.index(re)}
regex_to_use = regexes[positions.index(positions.compact.min)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...