Как заменить каждую подстроку в строке? - PullRequest
2 голосов
/ 31 марта 2020

У меня есть строка:

story = 'A long foo ago, in a foo bar baz, baz away...foobar'

У меня также есть совпадения из этой строки (словарь динамический c, это не зависит от меня)

string_matches = ['foo', 'foo', 'bar', 'baz', 'baz', 'foobar'] # words can be repeated

Как заменить каждый матч на **foo**? чтобы получить результат:

story = 'A long **foo** ago, in a **foo** **bar** **baz**, **baz** away...**foobar**'

например мой код:

string_matches.each do |word|
  story.gsub!(/#{word}/, "**#{word}**")
end

вернул:

"A long ****foo**** ago, in a ****foo**** **bar** ****baz****, ****baz**** away...****foo******bar**"

Ответы [ 2 ]

4 голосов
/ 31 марта 2020

Если вам нужно проверить, совпадают ли слова как целые слова, вы можете использовать

story.gsub(/\b(?:#{Regexp.union(string_matches.uniq.sort { |a,b| b.length <=> a.length }).source})\b/, '**\0**')

Если проверка всего слова не нужна, используйте

story.gsub(Regexp.union(string_matches.uniq.sort { |a,b| b.length <=> a.length }), '**\0**')

См. Ruby демо

Подробности

  • \b - граница слова
  • (?:#{Regexp.union(string_matches.uniq.sort { |a,b| b.length <=> a.length }).source}) - это создает шаблон, подобный (?:foobar|foo|bar|baz), который соответствует одному слову из дедуплицированного списка ключевых слов и сортирует их по длине в порядке убывания. См. Порядок оператора регулярного выражения (.. | .. ... .. | ..) почему это необходимо.
  • \b - граница слова

\0 в шаблоне замены - это обратная ссылка для замены, относящаяся ко всему совпадению.

0 голосов
/ 31 марта 2020

Небольшое изменение почти приведет вас туда:

irb(main):001:0> string_matches.uniq.each { |word| story.gsub!(/#{word}/, "**#{word}**") }
=> ["foo", "bar", "baz", "foobar"]
irb(main):002:0> story
=> "A long **foo** ago, in a **foo** **bar** **baz**, **baz** away...**foo****bar**"

Проблема с последней частью полученной строки заключается в том, что foobar соответствует и foo, и foobar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...