2017-10-04 23 views
2

まだマッチしている間に正規表現内のマッチのインデックスを見つけることは可能ですか?例:文字列内の正規表現一致のインデックスを見つける

str = "foo [bar] hello [world]" 
str.match(/\[(.*?)\]/) { |match,idx| 
    puts match 
    puts idx 
} 

残念ながら、idxはこの例ではnilです。

私の実際の問題は、いくつかの条件(たとえば、文字列がブラックリスト内にある場合など)に基づいて、括弧で囲まれた特定のサブストリングを置き換える文字列です。 worldがブラックリストに含まれている場合、"foo [bar] hello [world]""foo [bar] hello (world)"になるはずです。

+1

さらにエリックDuminilの提案に、私は私のコードをリファクタリングしています。私の回答を受け入れたので、更新を確認してください:) –

答えて

2

あなたはString#gsubを使用することができます。

blacklist = ["world"] 
str = "foo [bar] hello [world]" 

str.gsub(/\[(\w*?)\]/) { |m| 
    blacklist.include?($1) ? "(#{$1})" : m 
} 

#=> "foo [bar] hello (world)" 
+0

@eric私はあなたの提案を一致するグループに実装しました。ありがとう –

1

あなたはすべてのマッチオブジェクトと列挙子をしたい場合は、あなたが使用することができます。

def matches(string, regex) 
    position = 0 
    Enumerator.new do |yielder| 
    while match = regex.match(string, position) 
     yielder << match 
     position = match.end(0) 
    end 
    end 
end 

例としては:

p matches("foo [bar] hello [world]", /\[(.*?)\]/).to_a 
# [#<MatchData "[bar]" 1:"bar">, #<MatchData "[world]" 1:"world">] 
p matches("foo [bar] hello [world]", /\[(.*?)\]/).map{|m| [m[1], m.begin(0)]} 
# [["bar", 4], ["world", 16]] 

あなたはマッチオブジェクトからマッチした文字列とそのインデックスを取得することができます。

しかし、あなたはブロックでgsubを必要とするように、実際、それが見えます:

"foo [bar] hello [world]".gsub(/\[(.*?)\]/){ |m| # define logic here } 
関連する問題