4

#ハッシュタグ、@、または単語境界のいずれかに一致する正規表現を取得できないようです。目標は、文字列を Twitter のようなエンティティとトピックに分割することです。

input = "Hello @world, #ruby anotherString" 
input.scan(entitiesRegex) 
# => ["Hello", "@world", "#ruby", "anotherString"]

"anotherString"大きすぎる単語を除いて、単語だけを取得するのは簡単です。

/\b\w{3,12}\b/

戻り["Hello", "world", "ruby"]ます。@残念ながら、これにはハッシュタグとsが含まれていません。それは簡単に動作するはずです:

/[\b@#]\w{3,12}\b/

しかし、それは戻ります["@world", "#ruby"]。これにより、単語の境界は定義上文字ではないため、「単一の文字」のカテゴリに分類されず、一致しないことに気付きました。さらにいくつかの試み:

/\b|[@#]\w{3,12}\b/

戻ります["", "", "@world", "", "#ruby", "", "", ""]

/((\b|[@#])\w{3,12}\b)/

正しいものと一致しますが[[""], ["@"], ["#"], [""]]、中括弧は囲まれたすべてをキャプチャすることも意味するため、期待どおりに返されます。

/((\b|[@#])\w{3,12}\b)/

作品の種類。返します[["Hello", ""], ["@world", "@"], ["#ruby", "#"]]。これで、すべての正しいアイテムがそこにあり、各サブ配列の最初の要素に配置されています。次のスニペットは技術的に機能します。

input.scan(/((\b|[@#])\w{3,12}\b)/).collect(&:first)

collectこれを単純化して、後処理を必要としない正規表現だけで正しい部分文字列を一致させて返すことは可能ですか?

4

1 に答える 1

4

正規表現を使用するだけ/[@#]?\b\w+\b/です。つまり、オプションで@orに一致し#、その後に単語境界 ( では#ruby、その境界は と の間#にありruby、通常の単語では単語の先頭にも一致します) と一連の単語文字が続きます。

p "Hello @world, #ruby anotherString".scan(/[@#]?\b\w+\b/)
# => ["Hello", "@world", "#ruby", "anotherString"]

さらに、量指定子を使用して、一致する単語の文字数を調整できます。#rubyを使用してのみ一致するように、削除された回答へのコメントに例を示しました{3,4}

p "Hello @world, #ruby anotherString".scan(/[@#]?\b\w{3,4}\b/)
# => ["#ruby"]
于 2014-03-25T13:50:05.093 に答える