iOS 2.0でメールアドレスを検証するためのベストプラクティスは何ですか


167

ユーザーがiOS 2.0で入力するメールアドレスを検証する最もクリーンな方法は何ですか?

:これは、iOS 2.0に固有の歴史的な質問であり、その古さ、およびリンクされている他の質問の数により、廃止することはできず、「モダン」な質問に変更することはできません。


ココアの解決策を探しています。メールの有効性とメールの検証に関するルールを理解しています。ただし、Cocoa TouchではRegExに簡単にアクセスできないため、検証のためのCocoa Touchソリューションを探しています。検証に関するルールのリストではありません。
マーカスS.ザラ

これまでのところ、私が見つけた最良のコード提案は、RegExKitLiteと正規表現を使用することです。幸い、それは思ったよりも痛みが少ないです。
Marcus S. Zarra、

os <4.0をサポートしないアプリでのNSRegularExpressionの使用については、以下のコメントを参照してください。
2011

1
これはメールアドレスの検証に関する標準的な質問のようですので、iOSが成熟するにつれて改善された回答で更新することは理にかなっています。それを念頭に置いて、iOSを使用NSDataDetectorして電子メールアドレスを検証する回答を追加しました:stackoverflow.com/a/23547905/257550
memmons

2
この質問は、何年も前に廃止されたiOS 2.0に関するものであるため、トピックから外れているようです。
Nathan Eror

回答:


354

電子メールアドレスを検証するための正規表現の使用に対する回答は、RFC 5322で指定された文法がプリミティブな正規表現には複雑すぎることを非常に詳しく説明しています。

MKEmailAddressのような実際のパーサーアプローチをお勧めします。

簡単な正規表現ソリューションとして、DHValidationの次の変更を参照してください 。

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex =
@"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
@"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
@"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
@"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
@"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
@"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
@"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}

9
NSPredicateが利用できないため、素晴らしいがOS <3.0では動作しません。
Felixyz

4
いいね。NSPredicateが正規表現を実行できることを誰もが忘れています。
Rog、

5
これは非常に悪い正規表現です。たとえば、.museumのトップドメインを使用しているユーザーでは失敗します。この記事を参照してください:linuxjournal.com/article/9585
Jonny

18
cocoawithlove.com/2009/06/…には、この単純な正規表現の代わりに使用できる、より完全な正規表現があります。
Tomas Andrle 2010

12
ここに、ココア文字列としての非常に素朴ですが寛大な電子メール正規表現@"[^@]+@[^.@]+(\\.[^.@]+)+"があります。電子メールアドレスを確認する必要がある場合は、それにメッセージを送信して、成功するかどうかを確認してください。正規表現のみを使用してそれをいかなるレベルの正確さで検証することは決してないので、不必要に厳密な正規表現のために、ユーザーを怒らせたり、サインアップを失ったりしないようにするのが最善です。
Sami Samhuri、2009

20

RFCをお読みください。メールアドレスを解析/クリーンアップ/検証する方法を知っていると思っているほとんどすべての人が間違っています。

http://tools.ietf.org/html/rfc2822 セクション3.4.1は非常に役立ちます。通知

dtext = NO-WS-CTL /; 空白以外のコントロール

                        %d33-90 /; US-ASCIIの残りの部分
                        %d94-126; 「[」を含まない文字、
                                        ; 「]」または「\」

はい、つまり、+、 'などはすべて正当です。


2016年5月現在:RFC5322、セクション3.4.1
22

17

私がこれまでに見つけた最良の解決策(そして私が最終的に行った解決策)は、RegexKitLiteをプロジェクトに追加することです。これにより、NSStringカテゴリーを介して正規表現にアクセスできます。

プロジェクトに追加するのは非常に簡単で、配置すると、正規表現の電子メール検証ロジックが機能します。


5
NSPredicateは、プロジェクトにライブラリを追加することなくRegExを実行できます。
BadPirate

10
2009年4月からのこの質問は、NSPredicateがiOSに存在する前のものでした。
Marcus S. Zarra

7
繰り返しになりますが、NSRegularExpression はこの質問が行われたときにiOS 2.0では存在しませんでした。
Marcus S. Zarra

9
@ Marcus、Stack Overflowのポイントは、過去に特定の問題がどのように解決されたかの履歴を維持することではありません。とはいえ、2.0の互換性の角度を強調するために質問を編集しました。
ベンザド

2
タイトルを読んでください。これはiOS 2.0用で、Catlanのソリューションは存在しませんでした。
Marcus S. Zarra

10

まず始めに、何を決定し、メールアドレスとして受け入れたくないですか?

メールアドレスの99%は、bob.smith @ foo.comまたはfred@bla.eduのようになります。

ただし、次のようなメールアドレスを持つことは技術的には合法です:f !#$%&'*+-/=?^_{|}〜 "ha!" @ com

おそらく、トップレベルドメインの有効な電子メールはほんの一握りしかなく、他のほとんどの文字(特に引用符とバッククォート)を使用する人はほとんどいないので、これらはすべて無効なことであると想定した方がよいでしょう。しかし、あなたは意識的な決定としてそうすべきです。

それを超えて、Paulの言うことを行い、次のような正規表現に入力を一致させてみてください:^ [A-Z0-9 ._%+-] + @ [A-Z0-9 .-] +。[AZ] { 2、} $

それはほとんどすべての人のメールアドレスと一致します。


この回答は2009年に書かれたものですが、それでも検索結果では非常に高くなります。これはもはや最新ではなく、上記の正規表現は少し制限的であることを付け加えたかっただけです。たとえば、4桁以上のトップレベルドメインを使用できるようになりました
Jack

良い点は、「少なくとも2桁」に編集したことです。必要に応じて、さらに編集してください。
Brandon Yarbrough、2015

7

正規表現に焦点を当てることは良いですが、これは最初の必要なステップにすぎません。良い検証戦略を説明する必要がある他のステップがあります。

私の頭の上の2つのことは次のとおりです。

  1. ドメインが実際に存在することを確認するためのDNS検証。

  2. DNS検証後、SMTP検証を実行することもできます。smtpサーバーに呼び出しを送信して、ユーザーが実際に存在するかどうかを確認します。

このようにして、あらゆる種類のユーザーエラーをキャッチし、それが有効なメールであることを確認できます。


7

この機能はシンプルですが、メールアドレスをより徹底的にチェックします。たとえば、RFC2822によると、電子メールアドレスには、firstname..lastname @ domain..comのように、ピリオドが2つ続けて含まれていてはなりません。

この関数のように、正規表現でアンカーを使用することも重要です。アンカーがない場合、次の電子メールアドレスは有効と見なされます:first; name)lastname@domain.com(blah lastname@domain.comセクションは有効であるため、first; nameは無視されます)先頭と末尾のblah。アンカーは強制的にメール全体を検証する正規表現エンジン。

この関数は、iOS 2には存在しないNSPredicateを使用します。残念ながら、それは質問者には役立ちませんが、新しいバージョンのiOSで他の人を助けることができれば幸いです。この関数の正規表現は、iOS 2のRegExKitLiteにも適用できます。また、iOS 4以降を使用している場合は、これらの正規表現をNSRegularExpressionで実装できます。

- (BOOL)isValidEmail:(NSString *)email
{
    NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
    NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
    NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
    NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
}

Objective-Cの正規表現を使用してメールアドレスを検証するをご覧ください。


iOS 2.0にはNSPredicateがありませんでした。
マーカスS.ザラ2013年

2
しかし、この質問の用途とios 2の用途は何でしょうか。最新のos 7.1、つまりios 7.1を使用しています。iOS 6を使用することもできます
Gaurav Gilani

6
NSString *emailString = textField.text; **// storing the entered email in a string.** 
**// Regular expression to checl the email format.** 
NSString *emailReg = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; 
if (([emailTest evaluateWithObject:emailString] != YES) || [emailStringisEqualToString:@""]) 
{ 
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:@" Enter Email in" message:@"abc@example.com format" delegate:self 
cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

enter code here

[loginalert show]; 
[loginalert release]; 
} 
If email is invalid, it will remind the user with an alert box. 
Hope this might be helpful for you all. 

4

正規表現を使用すると、メールアドレスを検証するのに非常にうまく機能することがわかりました。

もちろん正規表現の主な欠点は保守性です。そのため、これまでにコメントしたことがないようなコメントを付けてください。約束しないと、数週間後に式に戻ったときにそうしたいと思うでしょう。

良い情報源へのリンクはhttp://www.regular-expressions.info/email.htmlです。


私は最近、そのページの最後から2番目のものを実装しましたが、とても満足しています。これは、完全な名前の引用符や角括弧がなく、単純なuser@host.comメールアドレスで正常に機能します。とにかくそのようなことをタイプしないWebフォーム検証に最適です。
zombat 2009

2
.museum TLDを持つ貧しい人々。
BadPirate

3

汚れを掘り下げましたが、完璧な仕事をし、素晴らしいインターフェースを備えたSHEmailValidatorを偶然見つけました。


この質問は、そのライブラリで使用されているNSPredicateや他のすべてのホストが含まれていないiOS 2.0に固有のものでした。
マーカスS.ザラ2013年

1
わかっていますが、「iosメール検証」を検索しているときに最初にここに着きました。たぶん将来、私は同じ検索を実行してここに着陸し、時間を節約するでしょう。
キリル

1

多くのWebサイトがRegExesを提供していますが、それらを学習して理解するだけでなく、実行したいことが電子メールアドレス形式の公式RFC内のニーズを満たしていることを確認することもできます。

RegExを学習する場合、インタープリター型言語は優れた簡素化機能とテストベッドになる可能性があります。RubularはRubyに基づいて構築されていますが、テストおよび検証するための優れた迅速な方法です。http://www.rubular.com/

それ以外に、O'Reillyの本「Mastering Regular Expressions」の最新版を購入してください。時間をかけて最初の3または4章を理解する必要があります。その後のすべては、高度に最適化されたRegExの使用に関する専門知識を構築します。

多くの場合、一連のより小さく、管理しやすいRegExesは、保守とデバッグが簡単です。


0

以下は、Swiftでメールを検証するStringの拡張です。

extension String {

    func isValidEmail() -> Bool {
        let stricterFilter = false
        let stricterFilterString = "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"
        let laxString = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$"
        let emailRegex = stricterFilter ? stricterFilterString : laxString
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

回答のコピー:iOSでメールアドレスが有効であることを確認する


NSPredicateiOS 2.0にはありませんでした
Marcus S. Zarra

-2

正規表現を使用してメールを検証しようとするべきではありません。TLDが常に変化しているため、バリデーターは不完全または不正確です。代わりに、NSDataDetector文字列を受け取り、既知のデータフィールド(電子メール、住所、日付など)があるかどうかを確認するAppleのライブラリを利用する必要があります。AppleのSDKはTLDを最新の状態に保つという重労働を行い、あなたは彼らの努力から便乗することができます!! :)

さらに、iMessage(またはその他のテキストフィールド)がメールではないと判断した場合は、メールと見なす必要がありますか?

この関数をNSStringカテゴリに配置したので、テストしている文字列はですself

- (BOOL)isValidEmail {
    // Trim whitespace first
    NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (self && self.length > 0) return NO;

    NSError *error = nil;
    NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
    if (!dataDetector) return NO;

    // This string is a valid email only if iOS detects a mailto link out of the full string
    NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
    if (error) return NO;
    return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}

または迅速なString拡張として

extension String {
    func isValidEmail() -> Bool {
        let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))

        return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
    }
}

1
この質問は8年前の質問です。
マーカスS.ザラ2017

1
それでも、あなたがグーグルならvalidate email objective-c、この質問は3番目の結果です。インターネット上のいくつかのものは古くなりません。:-)
Craig Otis

1
メールアドレスの検証に関連するすべての投稿の下で、この回答へのリンクをスパム送信しないでください。コメントは説明を求めるためのものであり、回答へのリンクをスパムするためのものではありません。
貧弱

ところで、NSDataDetectorこの質問はiOS 2.0には存在しませんでした。
マーカスS.ザラ2017

-7
// Method Call
NSString *email = @"Your Email string..";

BOOL temp = [self validateEmail:email];

if(temp)
{
// Valid
}
else
{
// Not Valid
}
// Method description

- (BOOL) validateEmail: (NSString *) email {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    BOOL isValid = [emailTest evaluateWithObject:email];
    return isValid;
}

3
このスレッド/質問はiOS 2用です。iOS2に NSPredicateは存在しませんでした。iOS 3まで追加されませんでした
Marcus S. Zarra '19年

3
あなたの答えが間違っているので私は答えた。質問は「iOS YでXをどのように行うか」であり、そのバージョンのiOSには存在しないフレームワークで答えました。
マーカスS.ザラ2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.