2

ActiveRecord を使用して、他のフィールドに関連する正規表現をデータベース テーブルに格納する必要があります。

私は述べているRegexpクラスでto_sメソッドを見つけました

正規表現とそのオプションを含む文字列を返します ((?opts:source) 表記を使用します。この文字列は、元と同じセマンティクスを持つ正規表現に Regexp::new にフィードバックできます。(ただし、Regexp#例が示すように、正規表現自体のソースが異なる可能性があるため、== は 2 つを比較するときに true を返さない場合があります) Regexp#inspect は、一般的に読みやすいバージョンの rxp を生成します。

したがって、これは有効な解決策のように見えますが、exp を通常とは異なる構文で格納するため、格納する文字列を取得するには、.xml を使用して手動でビルドする必要があり/my-exp/.to_sます。また、正規表現を直接編集できない場合があります。たとえば、単純な正規表現は次のようになります。

/foo/i.to_s # => "(?i-mx:foo)" 

もう 1 つのオプションは、フィールドの内容を評価することです。そのため、単純な式を db 列に格納してeval(record.pattern)から、実際の正規表現を取得するために を実行します。これは機能しており、正規表現レコードの管理を担当するのは私だけなので、アプリケーションのバグを除いて、それを行う上で問題はないはずです;-)

他に選択肢はありますか?私はdbフィールドでevalを実行したくないのですが、一方で、知らない構文で作業したくありません。

4

3 に答える 3

5

serialize正規表現を「そのまま」保存するために使用します

class Foo < ActiveRecord::Base
  serialize :my_regex, Regexp
end

詳細については、API ドキュメントを参照してください。

于 2012-10-25T12:00:17.617 に答える
3

あなたの制約を正確に理解しているかどうかはわかりません。

文字列を db に格納すると、そこから Regexp を作成できます。

a = 'foo'
=> "foo" 
/#{a}/
=> /foo/
Regexp.new('dog', Regexp::EXTENDED + Regexp::MULTILINE + Regexp::IGNORECASE) 
=> /dog/mix

他のコンストラクターがあります。 doc を参照してください。

eval されたコードを使用しないための最良の解決策は、正規表現部分を文字列列に格納し、フラグを別の整数列に格納することです。このようにして、正規表現は次のように構築できます。

record = Record.new pattern: 'foo', flags: Regexp::IGNORECASE
Regexp.new record.pattern, record.flags # => /foo/i
于 2012-10-25T11:30:53.227 に答える
2

正規表現内で #{} を使用して変数を挿入できるため、データベースの record.pattern の下に文字列として「foo」を格納し、次のように評価することで、慎重にクリーンな正規表現を挿入できます。

/#{record.pattern}/

したがって、データベースには次を保存します。

"pattern"

あなたのコードでは、次のことができます:

if record.other_field =~ /#{record.pattern}/
  # do something
end

これにより、変更可能なデータベース内の動的文字列から正規表現がコンパイルされ、コードで使用できるようになります。ただし、セキュリティ上の理由からお勧めしません。以下を参照してください。

正規表現にはルビーコードが含まれている可能性があるため、これは明らかに危険である可能性があるため、これはより単純ですが、危険という点では eval に似ています。

a = "foo"
puts a
=> foo
b = "#{a = 'bar'}"
a =~ /#{b}/ 
puts a 
=> bar

セキュリティのために、正規表現テストを、コードに記述したメソッドにマップできるものに分解する価値があるかどうかを検討することをお勧めします。そのため、次のような制約のためにデータベースにキーを保存できます。

「英字、数値」など

次に、保存されているキーに応じて実行するテストをハードコーディングします。ここでヒントのレール検証を見てください。それらはコードに保存されていますが、おそらく最良のアプローチです (要件を一般化し、コードをデータベースから除外します)。今はセキュリティが必要ないと思っていても、後でセキュリティが必要になるかもしれません。あるいは、このことを忘れて、悪意のある人物にアクセスを許可してしまうかもしれません。

于 2012-10-25T11:38:00.467 に答える