0

ユーザーのメールアドレスを検証するための正規表現があります。

/^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,})$/i"

アクティブレコードの助けを借りて、メールアドレスがこの正規表現と一致しないすべてのユーザーをデータベースから取得したいと思います。scope目的の結果を達成するために次のことを試みましたが、得られるのはActiveRecord::Relationです。

scope :not_match_email_regex, :conditions => ["NOT email REGEXP ?'", /^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,})$/"]

これにより、次のクエリが得られます。

SELECT `users`.* FROM `users` WHERE (email REGEXP '--- !ruby/regexp /^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\\-+)|([A-Za-z0-9]+\\.+)|([A-Za-z0-9]+\\++))*[A-Za-z0-9]+@((\\w+\\-+)|(\\w+\\.))*\\w{1,63}\\.[a-zA-Z]{2,})$/\n...\n')

また、これを次のように定義しようとするscopeと、同じ結果になります。

scope :not_match_email_regex, :conditions => ["email REGEXP '(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,})'"]

生成されるクエリは次のとおりです。

SELECT `users`.* FROM `users` WHERE (email REGEXP '(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+-+)|([A-Za-z0-9]+.+)|([A-Za-z0-9]+++))*[A-Za-z0-9]+@((w+-+)|(w+.))*w{1,63}.[a-zA-Z]{2,})')

指定された正規表現に一致する、または一致しないすべてのレコードをフェッチするにはどうすればよいですか?

4

2 に答える 2

2

@innocent_rifleのコメントに一部基づいて12-11-30の小さな修正を編集

ここで提案されている正規表現は、元の質問と同じ一致を作成しようとしています

1.最初に書いたときの私のソリューションでは\、MySQLで直接テストしていたため、文字列でエスケープする必要があることを忘れていました。正規表現について説明するときは、文字列で正規表現を使用すると混乱するため、代わりにこの形式を使用します。たとえば/dot\./.source、(Rubyで)どの形式を使用するとか"dot\\."

2. MySQLのREGEXP(5.6の手動、5.0.67でテスト済み)は「文字列のCエスケープ構文」を使用しているため、使用する必要のある文字を見つけるために、コードを使用する必要があることを実現するためにWHERE email REGEXP '\.'、と同じです。使用する方が読みやすいです(MySQLには2つのエスケープが必要です)。ただし、私はを使用することを好みます。そうすれば、必要なエスケープの数を心配する必要はありません。WHERE email REGEXP '.'"."WHERE email REGEXP '\\.'.where([ 'email REGEXP ?', "\\\\."]).where([ 'email REGEXP ?', /\\./.source ]).where([ 'email REGEXP ?', /[.]/.source ])

3.その文字が最初または最後である限り、正規表現"-"を使用する場合ではなく、正規表現でエスケープする必要はありません。[]


私が見つけたいくつかのエラー:それは最初の正規表現です-または「|」あなたの式では、それはクエリの文字列として、または私が好む正規表現#ソースを使用する必要があります。最後に余分な引用もあったと思います。それを除いて、あなたは本当に正規表現が機能することを確信しています。あなたが文字列のコンソールでそれを試してみたら?

また、dbでNULLを含む電子メールをキャッチしないことに注意してください。その場合は、追加する必要があります。(<your existing expr in parentheses>) OR IS NULL

MySQLバージョンの正規表現構文。

@Olaf Dietscheが彼の提案で書いたこともテストしました。これは必要ないようですが、とにかく標準の構文に従うことを強くお勧めしますNOT (expr REGEXP pat)(またはexpr NOT REGEXP pat)。

私はいくつかのチェックを行いました、これらのものを変更する必要があります:[A-Za-z0-9_]の代わりに使用し\w\+有効ではありません、あなたは\\+(文字列の場合)、(正規表現または文字列の両方"\\\\+"で)より簡単に使用する必要があります。[+]

MySQLでREGEXPをフォローすることになります

'^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+-+)|([A-Za-z0-9]+[.]+)|([A-Za-z0-9]+[+]+))*[A-Za-z0-9]+@(([A-Za-z0-9]+-+)|([A-Za-z0-9]+[.]))*[A-Za-z0-9]{1,63}[.][a-zA-Z]{2,}$'

小さな変更の提案

私はあなたの正規表現を正確に理解していません、それでこれはそれが見つけるものを変えることなくあなたの正規表現を変えるだけです。

まず、上記のように文字列全体を変更します

次に変更します

(([A-Za-z0-9]+_+)|([A-Za-z0-9]+-+)|([A-Za-z0-9]+[.]+)|([A-Za-z0-9]+[+]+))*

([A-Za-z0-9]+[-+_.]+)*

@(([A-Za-z0-9]+-+)|([A-Za-z0-9]+[.]))*

@([A-Za-z]+[-.]+)*

最終コード..., :conditions => ...(必要に応じて構文に変更してください)。@innocent_rifleのコメントと同じ文字列を検索するように試みましたが"_"、の右側に式を追加するだけです。@

.where([ 'NOT (email REGEXP ?)', /^([A-Za-z0-9]+[-+_.]+)*[A-Za-z0-9]+@([A-Za-z0-9]+[-._]+)*[A-Za-z0-9_]{1,63}[.][A-Za-z]{2,}$/.source ])
于 2012-11-23T13:42:52.623 に答える
0

電子メールアドレスを検証するために、電子メールアドレスを検索または検証する方法を検討することをお勧めします。少なくとも、この正規表現は少し単純に見えます。

MySQLによると-正規表現適切な構文は

expr REGEXP pat

試合のために、そして

expr NOT REGEXP patまたNOT (expr REGEXP pat)

反対に。2番目のバージョンの中括弧を忘れないでください。

于 2012-11-23T14:10:01.293 に答える