2011-10-03 11 views
6

私はこれは愚かな間違いだと思いますが、私にとっては以下のコードは "M"だけの配列を返します。これを参照してください:Ruby Regex、1つだけのキャプチャ(非常に単純!)

/(.)+?/.match("Many many characters!").captures 
=> ["M"] 

なぜすべての文字の配列を返しませんか?私はこれに何が間違っているのか分からないので、何かが大変明らかに欠けていたに違いない。

編集:ちょうど実現しました、私は+を必要としません?それがなければまだ動作しません。

編集:謝罪!私は明確にします:私の目標は、ユーザーが正規表現とスタイリングと入力テキストファイルを入力できるようにすることです。一致する箇所があれば、テキストはhtml要素で囲まれ、スタイリングが適用されます。文字列を文字に変換するには、与えられた正規表現を使用しました。なぜなら、それは私の部分では愚かでしたが、最も簡単だったからです。 scan()からキャプチャグループを取得するにはどうすればいいのですか?私は$ 1が "!" (最後の試合?)、他にはありません。

編集:まあ、それは本当に私の日ではありません。私が死亡したことが通知されたので、キャプチャは別々の配列に格納されます。これらのキャプチャの元の文字列からのオフセットを取得するにはどうすればよいですか?キャプチャのオフセットを取得して別の文字列で囲むことができるようにしたいと思います。それともgsubは何のためですか?うまくいけば、最終的な編集

(私はキャプチャグループは、唯一のマッチを置き換えることではないと思った):右、私はちょうどこれを再び起動してみましょう:P

だから、私は文字列を持っています。ユーザーは設定ファイルを使用して正規表現を入力し、次に各キャプチャグループに関連付けられたスタイルを入力します。私は文字列全体をスキャンし、各グループのマッチの開始と終了またはオフセットとサイズを取得する必要があります。

ユーザーが([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})(電子メールアドレス)を構成していたのであれば、私は得ることができる必要があります:

[ ["elliotpotts", 0, 11], 
    ["sample.",  12, 7], 
    ["com",   19, 3] ] 

を文字列から: 「[email protected]

それがない場合には明らかに、私には何か間違っているだけです:P。これまでの多くの人におかげでありがとう、そしてとても忍耐強くてくれてありがとう!

+0

私はあなたの編集を見ましたが、スキャンからのキャプチャグループは別々の配列に格納されています。あなたの正規表現とテスト文字列をirbで試してみてください。あなたの次の編集を見ただけで、より多くの情報で更新する必要があります。 –

+0

私はちょっと混乱しています:Pあなたが抽出する必要があるものを正確に知っているので、それが何であるかに関係なく、より完全な例を自由に投げてください。 –

+0

あなたの最新の編集で私の答えを更新しました。私はちょっと結びついているので、解説のない完全な解決策です。理解できない場合は教えてください。 –

答えて

9

をキャプチャだけ単一の文字にマッチしているので:あなたはおそらく代わりにscanを使用します。

"Many many characters!".scan(/./) 
#=> ["M", "a", "n", "y", " ", "m", "a", "n", "y", " ", "c", "h", "a", "r", "a", "c", "t", "e", "r", "s", "!"] 

注:あなたはスキャンを使用したキャプチャグループ

を気にしない場合、すべての文字が再帰的にString#scanまたはString#splitを使用一致させたい場合は(.)+(.+)

>> /(.)+?/.match("Many many characters!").captures 
=> ["M"] 
>> /(.+)?/.match("Many many characters!").captures 
=> ["Many many characters!"] 
>> /(.+?)/.match("Many many characters!").captures 
=> ["M"] 

と同じではありません他の答えは(.)を使用していますが、キャプチャグループを気にしているのであれば問題ありません。そうでなければ少し無意味です。そうでないと、すべてのキャラクターが返されますn個の別々の配列は、次のように:あなたの編集への返信で"Many many characters!".split(' ')"

EDIT:それ以外の場合は

[["M"], ["a"], ["n"], ["y"], [" "], ["m"], ["a"], ["n"], ["y"], [" "], ["c"], ["h"], ["a"], ["r"], ["a"], ["c"], ["t"], ["e"], ["r"], ["s"], ["!"]] 

、ちょうどsplit使用

reg = /([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})/ 
str = "[email protected]" 
str.scan(reg).flatten.map { |capture| [capture, str.index(capture), capture.size] } 
#=> [["elliotpotts", 0, 11], ["sample.", 12, 7], ["com", 19, 3]]` 

ああ、あなたはスキャンを必要としませんあなたは本当にスキャンしていないので、少なくともあなたが指定した例ではトラバースする必要はありません:

str.match(reg).captures.map { |capture| [capture, str.index(capture), capture.size] } 

+0

ありがとう!私はまた別の答えを見つけて、それを今投稿します。ありがとうございました! – Ell

+0

与えられた2つのコードスニペットは、一般的な場合のオフセットに対して正しく機能しません。一致した部分文字列がすべて異なる場合にのみ機能します。たとえば、 "h"に3つの一致がある場合、同じインデックス( 'h'の最初のインスタンス)が3回すべて返されます。 str.index(capture)は、取り込まれた部分文字列の最初のインスタンスのインデックスを返します。 – jpwynn

0

これは1文字のみを返すことです。これは、それがあなたにマッチするように頼んだからです。

str = "Many many characters!" 
matches = str.scan(/(.)/) 
1

はい、重要な何かが;-)

(...)を逃したが動作する唯一ONEキャプチャグループが導入されています。インデックスがのみ定期によって決定されるように、グループが一致した回数は関係ありません入力自体ではなく、表現自体です。

キーは「グローバル正規表現」で、正規表現を複数回順番に適用します。 Rubyでは、これはString#scanRegex#matchから反転して行われます(他の多くの言語には、「/ G」正規表現修飾子を持つ):

"Many many chara­cters!".sc­an(/(.)+?/­) 
# but more simply (or see answers using String#split) 
"Many many chara­cters!".sc­an(/(.)/­) 

ハッピーコーディング

0

次のコードは、Get index of string scan results in rubyからのものであり、私の好みのために変更します。

[].tap {|results| 
    "abab".scan(/a/) {|capture| 
     results.push(([capture, Regexp::last_match.offset(0)]).flatten) 
    } 
} 

=> [["a", 0], ["a", 2]] 
関連する問題