6

私のアプリでは、すべての数値の部分文字列を見つけて、それぞれをスキャンし、範囲(5〜15など)に一致する最初の部分文字列を見つけて、そのインスタンスを別の文字列「X」に置き換える必要があります。

私のテスト文字列s = "1 foo 100 bar 10 gee 1"

私の最初のパターンは、1桁以上の任意の文字列です。re = Regexp.new(/\d+/)

matches = s.scan(re)与える["1", "100", "10", "1"]

N番目の一致のみを「X」に置き換えたい場合はどうすればよいですか?

たとえば、3番目の一致「10」(matches [2])を置き換えたい場合、 s[matches[2]] = "X"2つの置き換えが行われるため、単純に言うことはできません。

"1 foo X0 bar X gee 1"

どんな助けでもいただければ幸いです!

4

2 に答える 2

8

String#gsubブロックをとる形をしています。一致するたびにブロックに譲り、一致をブロックの結果に置き換えます。それで:

first = true
"1 foo 100 bar 10 gee 1 12".gsub(/\d+/) do |digits|
  number = digits.to_i
  if number >= 5 && number <= 15 && first
    # do the replacement
    first = false
    'X'
  else
    # don't replace; i.e. replace with itself
    digits
  end
end
# => "1 foo 100 bar X gee 1 12" 
于 2012-09-21T04:15:31.560 に答える
1

別の方法は、文字クラスを使用して数値範囲を作成することです(それほど複雑でない場合)

>> s = "1 foo 100 bar 10 gee 1"
=> "1 foo 100 bar 10 gee 1"
>> s.sub(/(?<!\d)([5-9]|1[0-5])(?!\d)/, 'X')
=> "1 foo 100 bar X gee 1"
  • ネガティブルックアラウンドは、数字シーケンスの一部が一致しないことを保証します
    • 数字を次のような\b単語の一部にすることができない場合は、ルックアラウンドの代わりに使用できます。abc12ef8foo
  • ([5-9]|1[0-5])5から15までの数字に一致します


最初、タイトルから、N番目のオカレンスを置き換えたいと思いました。たとえば、N = 2は、任意の数字シーケンスの2番目のオカレンスを置き換えることを意味します。そのためにあなたはこれを使うことができます:

# here the number inside {} will be N-1
>> s.sub(/(\d+.*?){1}\K\d+/, 'X')
=> "1 foo X bar 10 gee 1"
于 2018-09-25T14:54:26.300 に答える