Input.gsub(numbers) {| m | p $~} Согласование данных в Ruby для всех вхождений строки

Ответ от Как получить данные соответствия для всех вхождений регулярного выражения Ruby в строку?:

input = "abc12def34ghijklmno567pqrs"
numbers = /\d+/
input.gsub(numbers) { |m| p $~ }

Результат выполняется по запросу:

⇒ #<MatchData "12">
⇒ #<MatchData "34">
⇒ #<MatchData "567">

Кто-нибудь сломает то, что делает ответчик в input.gsub(numbers) { |m| p $~ }?

Также, как я могу получить доступ к каждому из MatchData s?

Ответ 1

Так как я ответчик, я попытаюсь объяснить.

$~ является одним из предопределенных глобальных переменных Ruby. Он возвращает MatchData из предыдущего успешного совпадения с шаблоном. К нему можно получить доступ, используя Regexp.last_match.

Как указанный в документации, gsub с блоком обычно используется для изменения строки, но здесь мы используем тот факт, что он вызывает блок-блок на каждом матче. Блочная переменная m существует простая строка для этого соответствия, поэтому, нужен ли нам весь экземпляр MatchData, мы должны использовать предопределенный глобальный $~. В приведенном примере мы просто напечатаем каждый MatchData с помощью p $~.

Трюк здесь в том, что $~ возвращает последний MatchData. Итак, все, что вам нужно, это использовать переменную $~, несмотря на ее отталкивающий взгляд. Или вы можете установить:

my_beauty_name_match_data_var = $~

и играть с последним. Надеюсь, что это поможет.