Regex, email address validation
От: whatever  
Дата: 10.08.09 08:38
Оценка:
Задача — проверять правильность адреса электронной почты на этапе ввода, .Net Framework 3.5.
Казалось бы, всё просто. В справке к MSVS 2008 находим код:
bool IsValidEmail(string strIn)
{
    // Return true if strIn is in valid e-mail format.
    return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); 
}

Проверяем адрес dприветd@dмедведd.ru — валидный! Ладно, кириллические домены уже вот-вот появятся, и пусть этот адрес будет валидный, но когда я пытаюсь создать экземпляр класса MailAddress, вылетает сюрприз:
System.FormatException: The specified string is not in the form required for an e-mail address.
at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset, String& displayName)
at System.Net.Mail.MailAddress.ParseValue(String address)
at System.Net.Mail.MailAddress..ctor(String address, String displayName, Encoding displayNameEncoding)

В MSDN нашёлся другой код (исправленный в июле 2009, что навеяло надежду):
public static bool IsValidEmail(string strIn)
{
    // Return true if strIn is in valid e-mail format.
    return Regex.IsMatch(strIn, @"^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$"); 
}

Но результат тот же. Опыта работы с регулярными выражениями у меня нет, поэтому прошу помощи в отсеивании адресов с русскими буквами. Или правильнее будет вместо использования регулярных выражений пытаться создать MailAddress, и в случае исключения возвращать false?
Re: Regex, email address validation
От: cadet354 Россия
Дата: 10.08.09 11:09
Оценка:
Здравствуйте, whatever, Вы писали:

W>Задача — проверять правильность адреса электронной почты на этапе ввода, .Net Framework 3.5.

1-ое выражение не работает т.к. \w это символ не whitespace, и русские буквы проходят, второе должно работать (но содержит ошибку аналогичную первой, исправлено жирным):
void Main()
{
    string address="dприветd@mail.ru";
    if (Regex.IsMatch(address, @"^([0-9a-zA-Z]([-\.0-9a-zA-Z]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})"))
    {
        Console.WriteLine("true");
    }
    else{
        Console.WriteLine("false");
    }
}

выводит "false".
P.S. А вообще полная проверка регексп согласно стандарту, это такой фарш на полстраницы (гугли)
... << RSDN@Home 1.2.0 alpha 4 rev. 1231>>
Re[2]: Regex, email address validation
От: Danchik Украина  
Дата: 10.08.09 12:02
Оценка: 1 (1)
Здравствуйте, cadet354, Вы писали:

[Skip]

C>P.S. А вообще полная проверка регексп согласно стандарту, это такой фарш на полстраницы (гугли)


Можна начинать рыть отсюда, включая гиперлинки
RFC-5322 (Address Specification)
Re: Regex, email address validation
От: Kore Sar  
Дата: 10.08.09 12:10
Оценка: -1
С той же проблемой боролся. Пришел к выводу, что проще, быстрее, понятнее — это написать функцию, которая тупым перебором по символам проверяет валидность.
Re: Regex, email address validation
От: Lloyd Россия  
Дата: 10.08.09 12:15
Оценка:
Здравствуйте, whatever, Вы писали:

W>Но результат тот же. Опыта работы с регулярными выражениями у меня нет, поэтому прошу помощи в отсеивании адресов с русскими буквами.


Почему бы просто не посмотреть в Reflector-е, как реализован MailAddress?
Re[2]: Regex, email address validation
От: whatever  
Дата: 10.08.09 12:22
Оценка:
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, whatever, Вы писали:


W>>Задача — проверять правильность адреса электронной почты на этапе ввода, .Net Framework 3.5.

C>1-ое выражение не работает т.к. \w это символ не whitespace, и русские буквы проходят, второе должно работать (но содержит ошибку аналогичную первой, исправлено жирным):
C>
C>void Main()
C>{
C>    string address="dприветd@mail.ru";
C>    if (Regex.IsMatch(address, @"^([0-9a-zA-Z]([-\.0-9a-zA-Z]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})"))
C>    {
C>        Console.WriteLine("true");
C>    }
C>    else{
C>        Console.WriteLine("false");
C>    }
C>}
C>

C>выводит "false".
C>P.S. А вообще полная проверка регексп согласно стандарту, это такой фарш на полстраницы (гугли)


Спасибо, удовлетворился этим:
return System.Text.RegularExpressions.Regex.IsMatch(address, @"^([0-9a-zA-Z]([-\.0-9a-zA-Z]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\.0-9a-zA-Z]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$");
Re[2]: Regex, email address validation
От: whatever  
Дата: 10.08.09 12:27
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, whatever, Вы писали:


W>>Но результат тот же. Опыта работы с регулярными выражениями у меня нет, поэтому прошу помощи в отсеивании адресов с русскими буквами.


L>Почему бы просто не посмотреть в Reflector-е, как реализован MailAddress?


Смотрел, не понравилось. Там всё гораздо сложнее, чем нужно мне.
Re[2]: Regex, email address validation
От: cadet354 Россия
Дата: 10.08.09 13:59
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, whatever, Вы писали:


W>>Но результат тот же. Опыта работы с регулярными выражениями у меня нет, поэтому прошу помощи в отсеивании адресов с русскими буквами.


L>Почему бы просто не посмотреть в Reflector-е, как реализован MailAddress?

я тоже так подумал, глянул, и понял, что это так же не понятно, как фарш на полстраницы регекспа
internal static string ReadMailAddress(string data, ref int offset, out string displayName)
{
    string str = null;
    Exception exception = null;
    displayName = string.Empty;
    StringBuilder builder = new StringBuilder();
    try
    {
        SkipCFWS(data, ref offset);
        if (offset >= data.Length)
        {
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
            goto Label_0270;
        }
        if (data[offset] == '<')
        {
            offset++;
            return ReadAngleAddress(data, ref offset, builder);
        }
        ReadPhrase(data, ref offset, builder);
        if (offset >= data.Length)
        {
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
            goto Label_0270;
        }
        char ch = data[offset];
        if (ch <= '.')
        {
            switch (ch)
            {
                case '"':
                    goto Label_016C;

                case '.':
                    goto Label_00D9;
            }
            goto Label_0211;
        }
        switch (ch)
        {
            case ':':
                exception = new FormatException(SR.GetString("MailAddressUnsupportedFormat"));
                goto Label_0270;

            case ';':
                goto Label_0211;

            case '<':
                displayName = builder.ToString();
                builder = new StringBuilder();
                offset++;
                str = ReadAngleAddress(data, ref offset, builder);
                goto Label_0223;

            default:
                if (ch != '@')
                {
                    goto Label_0211;
                }
                offset++;
                str = ReadAddressSpecDomain(data, ref offset, builder);
                goto Label_0223;
        }
    Label_00D9:
        ReadDotAtom(data, ref offset, builder);
        SkipCFWS(data, ref offset);
        if (offset >= data.Length)
        {
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
        }
        else
        {
            if (data[offset] == '@')
            {
                offset++;
                str = ReadAddressSpecDomain(data, ref offset, builder);
                goto Label_0223;
            }
            if (data[offset] == '<')
            {
                displayName = builder.ToString();
                builder = new StringBuilder();
                offset++;
                str = ReadAngleAddress(data, ref offset, builder);
                goto Label_0223;
            }
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
        }
        goto Label_0270;
    Label_016C:
        offset++;
        if (offset >= data.Length)
        {
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
            goto Label_0270;
        }
        SkipCFWS(data, ref offset);
        if (offset >= data.Length)
        {
            exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
            goto Label_0270;
        }
        if (data[offset] == '<')
        {
            offset++;
            str = ReadAngleAddress(data, ref offset, builder);
        }
        else
        {
            str = ReadAddressSpecDomain(data, ref offset, builder);
        }
        goto Label_0223;
    Label_0211:
        exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
        goto Label_0270;
    Label_0223:
        if (offset < data.Length)
        {
            SkipCFWS(data, ref offset);
            if ((offset < data.Length) && (data[offset] != ','))
            {
                exception = new FormatException(SR.GetString("MailAddressInvalidFormat"));
            }
        }
    }
    catch (FormatException)
    {
        throw new FormatException(SR.GetString("MailAddressInvalidFormat"));
    }
Label_0270:
    if (exception != null)
    {
        throw exception;
    }
    return str;
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1231>>
Re: Regex, email address validation
От: Warturtle  
Дата: 10.08.09 14:23
Оценка:
Здравствуйте, whatever, Вы писали:

W>Задача — проверять правильность адреса электронной почты на этапе ввода, .Net Framework 3.5.

W>Казалось бы, всё просто. В справке к MSVS 2008 находим код:
W>
W>bool IsValidEmail(string strIn)
W>{
W>    // Return true if strIn is in valid e-mail format.
W>    return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); 
W>}
W>

W>Проверяем адрес dприветd@dмедведd.ru — валидный! Ладно, кириллические домены уже вот-вот появятся, и пусть этот адрес будет валидный, но когда я пытаюсь создать экземпляр класса MailAddress, вылетает сюрприз:
W>System.FormatException: The specified string is not in the form required for an e-mail address.
W> at System.Net.Mime.MailBnfHelper.ReadMailAddress(String data, Int32& offset, String& displayName)
W> at System.Net.Mail.MailAddress.ParseValue(String address)
W> at System.Net.Mail.MailAddress..ctor(String address, String displayName, Encoding displayNameEncoding)

W>В MSDN нашёлся другой код (исправленный в июле 2009, что навеяло надежду):

W>
W>public static bool IsValidEmail(string strIn)
W>{
W>    // Return true if strIn is in valid e-mail format.
W>    return Regex.IsMatch(strIn, @"^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$"); 
W>}
W>

W>Но результат тот же. Опыта работы с регулярными выражениями у меня нет, поэтому прошу помощи в отсеивании адресов с русскими буквами. Или правильнее будет вместо использования регулярных выражений пытаться создать MailAddress, и в случае исключения возвращать false?
зацени
Re[3]: Regex, email address validation
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.08.09 22:14
Оценка: 93 (1)
Здравствуйте, cadet354, Вы писали:

C>я тоже так подумал, глянул, и понял, что это так же не понятно, как фарш на полстраницы регекспа


Видимо потому что некоторые не в курсе, что вместо рефлектора можно использовать сами исходники.
//-----------------------------------------------------------------------------
// <copyright file="MailBnfHelper.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace System.Net.Mime
{
    using System;
    using System.Text;
    using System.Net.Mail;
    using System.Globalization;

    internal static class MailBnfHelper
    {
        static bool[] s_atext = new bool[128];
        static bool[] s_qtext = new bool[128];
        static bool[] s_fqtext = new bool[128];
        static bool[] s_dtext = new bool[128];
        static bool[] s_fdtext = new bool[128];
        static bool[] s_ftext = new bool[128];
        static bool[] s_ttext = new bool[128];
        static bool[] s_digits = new bool[128];

        static MailBnfHelper()
        {
            // atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
            for (int i = '0'; i <= '9'; i++) { s_atext[i] = true; }
            for (int i = 'A'; i <= 'Z'; i++) { s_atext[i] = true; }
            for (int i = 'a'; i <= 'z'; i++) { s_atext[i] = true; }
            s_atext['!'] = true;
            s_atext['#'] = true;
            s_atext['$'] = true;
            s_atext['%'] = true;
            s_atext['&'] = true;
            s_atext['\''] = true;
            s_atext['*'] = true;
            s_atext['+'] = true;
            s_atext['-'] = true;
            s_atext['/'] = true;
            s_atext['='] = true;
            s_atext['?'] = true;
            s_atext['^'] = true;
            s_atext['_'] = true;
            s_atext['`'] = true;
            s_atext['{'] = true;
            s_atext['|'] = true;
            s_atext['}'] = true;
            s_atext['~'] = true;

            // qtext = %d1-8 / %d11 / %d12 / %d14-31 / %d33 / %d35-91 / %d93-127
            for (int i = 1; i <= 8; i++) { s_qtext[i] = true; }
            s_qtext[11] = true;
            s_qtext[12] = true;
            for (int i = 14; i <= 31; i++) { s_qtext[i] = true; }
            s_qtext[33] = true;
            for (int i = 35; i <= 91; i++) { s_qtext[i] = true; }
            for (int i = 93; i <= 127; i++) { s_qtext[i] = true; }

            // fqtext = %d1-9 / %d11 / %d12 / %d14-33 / %d35-91 / %d93-127
            for (int i = 1; i <= 9; i++) { s_fqtext[i] = true; }
            s_fqtext[11] = true;
            s_fqtext[12] = true;
            for (int i = 14; i <= 33; i++) { s_fqtext[i] = true; }
            for (int i = 35; i <= 91; i++) { s_fqtext[i] = true; }
            for (int i = 93; i <= 127; i++) { s_fqtext[i] = true; }

            // dtext = %d1-8 / %d11 / %d12 / %d14-31 / %d33-90 / %d94-127
            for (int i = 1; i <= 8; i++) { s_dtext[i] = true; }
            s_dtext[11] = true;
            s_dtext[12] = true;
            for (int i = 14; i <= 31; i++) { s_dtext[i] = true; }
            for (int i = 33; i <= 90; i++) { s_dtext[i] = true; }
            for (int i = 94; i <= 127; i++) { s_dtext[i] = true; }

            // fdtext = %d1-9 / %d11 / %d12 / %d14-90 / %d94-127
            for (int i = 1; i <= 9; i++) { s_fdtext[i] = true; }
            s_fdtext[11] = true;
            s_fdtext[12] = true;
            for (int i = 14; i <= 90; i++) { s_fdtext[i] = true; }
            for (int i = 94; i <= 127; i++) { s_fdtext[i] = true; }

            // ftext = %d33-57 / %d59-126
            for (int i = 33; i <= 57; i++) { s_ftext[i] = true; }
            for (int i = 59; i <= 126; i++) { s_ftext[i] = true; }

            // ttext = %d33-126 except '()<>@,;:\"/[]?='
            for (int i = 33; i <= 126; i++) { s_ttext[i] = true; }
            s_ttext['('] = false;
            s_ttext[')'] = false;
            s_ttext['<'] = false;
            s_ttext['>'] = false;
            s_ttext['@'] = false;
            s_ttext[','] = false;
            s_ttext[';'] = false;
            s_ttext[':'] = false;
            s_ttext['\\'] = false;
            s_ttext['"'] = false;
            s_ttext['/'] = false;
            s_ttext['['] = false;
            s_ttext[']'] = false;
            s_ttext['?'] = false;
            s_ttext['='] = false;

            // digits = %d48-57
            for (int i = 48; i <= 57; i++)
                s_digits[i] = true;
        }





        internal static bool SkipCFWS(string data, ref int offset)
        {
            int comments = 0;
            for (;offset < data.Length ;offset++)
            {
                if (data[offset] > 127)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                else if (data[offset] == '\\' && comments > 0)
                    offset += 2;
                else if (data[offset] == '(')
                    comments++;
                else if (data[offset] == ')')
                    comments--;
                else if (data[offset] != ' ' && data[offset] != '\t' && comments == 0)
                    return true;

                if (comments < 0) {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
            }

            //returns false if end of string
            return false;
        }

        
        internal static bool SkipFWS(string data, ref int offset)
        {
            for (;offset < data.Length ;offset++)
            {
                if (data[offset] != ' ' && data[offset] != '\t')
                    return true;
            }

            //returns false if end of string
            return false;
        }


        internal static void ValidateHeaderName(string data){
            int offset = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_ftext.Length || !s_ftext[data[offset]])
                    throw new FormatException(SR.GetString(SR.InvalidHeaderName));
            }
            if (offset == 0)
                throw new FormatException(SR.GetString(SR.InvalidHeaderName));
        }


        /*
        // Consider removing.
        internal static string ReadFieldName(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] == ':')
                    break;
                if (data[offset] > s_ftext.Length || !s_ftext[data[offset]])
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
            }
            if (start == 0 && offset == data.Length)
                return data;
            else
                return data.Substring(start, offset - start);
        }
        */

        internal static string ReadQuotedString(string data, ref int offset, StringBuilder builder){
            return ReadQuotedString(data, ref offset, builder,false);
        }

        internal static string ReadQuotedString(string data, ref int offset, StringBuilder builder,bool doesntRequireQuotes)
        {
            // assume first char is the opening quote
            if(!doesntRequireQuotes){
                ++offset;
            }
            int start = offset;
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            for (; offset < data.Length; offset++)
            {
                if (data[offset] == '\\')
                {
                    localBuilder.Append(data, start, offset - start);
                    start = ++offset;
                    continue;
                }
                else if (data[offset] == '"')
                {
                    localBuilder.Append(data, start, offset - start);
                    offset++;
                    return (builder != null ? null : localBuilder.ToString());
                }
                else if (!s_fqtext[data[offset]])
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
            }
            if(doesntRequireQuotes){
                localBuilder.Append(data, start, offset - start);
                return (builder != null ? null : localBuilder.ToString());
            }
            throw new FormatException(SR.GetString(SR.MailHeaderFieldMalformedHeader));
        }

        internal static string ReadPhrase(string data, ref int offset, StringBuilder builder)
        {
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            bool addSP = false;
            SkipCFWS(data, ref offset);
            int start = offset;

            while (SkipCFWS(data, ref offset))
            {
                if (data[offset] == '"')
                {
                    if (addSP)
                        localBuilder.Append(' ');
                    ReadQuotedString(data, ref offset, localBuilder);
                    addSP = true;
                }
                else if (s_atext[data[offset]])
                {
                    if (addSP)
                        localBuilder.Append(' ');
                    ReadAtom(data, ref offset, localBuilder);
                    addSP = true;
                }
                else
                {
                    break;
                }
            }
            if (start == offset) {
                //we didn't get any text, which is a violation
                throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
            }

            return (builder != null ? null : localBuilder.ToString());
        }

        internal static string ReadAtom(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            string ret;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
                else if (!s_atext[data[offset]])
                {

                    //if we didn't find any data, then there was an error.
                    if(offset == start){
                        throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                    }

                    ret = data.Substring(start, offset - start);
                    if (builder != null)
                    {
                        builder.Append(ret);
                        return null;
                    }
                    else
                    {
                        return ret;
                    }
                }
            }


            //if we didn't find any data, then there was an error.
            if(offset == start){
                throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
            }
            
            ret = (start == 0 ? data : data.Substring(start));
            if (builder != null)
            {
                builder.Append(ret);
                return null;
            }
            else
            {
                return ret;
            }
        }


        internal static string ReadDotAtom(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            bool validBuilder = true;
            if (builder == null){
                validBuilder = false;
                builder = new StringBuilder();
            }

            if(data[offset]!='.'){
                ReadAtom(data,ref offset, builder);
            }

            while(offset < data.Length && data[offset]=='.') {
                builder.Append(data[offset++]);
                ReadAtom(data,ref offset, builder);
            }

            if(validBuilder){
                return null;
            }
            else{
                return builder.ToString();
            }
        }
        
        
        /*
        // Consider removing.
        internal static string ReadAddress(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            if (!SkipCFWS(data, ref offset))
                return null;

            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            
            if (data[offset] == '"')
                ReadQuotedString(data, ref offset, localBuilder);
            else
                ReadDotAtom(data, ref offset, localBuilder);

            if (!SkipCFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));

            if (data[offset++] != '@')
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));

            if (!SkipCFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));

            localBuilder.Append('@');

            if (data[offset] == '[')
                ReadDomainLiteral(data, ref offset, localBuilder);
            else
                ReadDotAtom(data, ref offset, localBuilder);

            return (builder != null ? null : localBuilder.ToString());
        }
        */


        internal static string ReadDomainLiteral(string data, ref int offset, StringBuilder builder)
        {
            // assume first char is the opening bracket
            int start = ++offset;
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            for (; offset < data.Length; offset++)
            {
                if (data[offset] == '\\')
                {
                    localBuilder.Append(data, start, offset - start);
                    start = ++offset;
                    continue;
                }
                else if (data[offset] == ']')
                {
                    localBuilder.Append(data, start, offset - start);
                    offset++;
                    return (builder != null ? null : localBuilder.ToString());
                }
                else if (data[offset] > s_fdtext.Length || !s_fdtext[data[offset]])
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
            }
            throw new FormatException(SR.GetString(SR.MailHeaderFieldMalformedHeader));
        }

        internal static string ReadParameterAttribute(string data, ref int offset, StringBuilder builder)
        {
            if (!SkipCFWS(data, ref offset))
                return null; // TODO: is this correct?

            return ReadToken(data, ref offset, null);
        }

        /*
        // Consider removing.
        internal static string ReadParameterValue(string data, ref int offset, StringBuilder builder)
        {
            if (!SkipCFWS(data, ref offset))
                return string.Empty;

            if (data[offset] == '"')
                return ReadQuotedString(data, ref offset, builder);
            else
                return ReadToken(data, ref offset, builder);
        }
        */

        internal static string ReadToken(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_ttext.Length)
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
                else if (!s_ttext[data[offset]])
                {
                    break;
                }
            }

            if (start == offset) {
                throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
            }

            return data.Substring(start, offset - start);
        }

        /*
        // Consider removing.
        internal static string ReadNoFoldQuotedString(string data, ref int offset, StringBuilder builder)
        {
            // assume first char is the opening quote
            int start = ++offset;
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            for (; offset < data.Length; offset++)
            {
                if (data[offset] == '\\')
                {
                    localBuilder.Append(data, start, offset - start);
                    start = ++offset;
                    continue;
                }
                else if (data[offset] == '"')
                {
                    localBuilder.Append(data, start, offset - start);
                    offset++;
                    return (builder != null ? null : localBuilder.ToString());
                }
                else if (data[offset] > s_qtext.Length || !s_qtext[data[offset]])
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
            }
            throw new FormatException(SR.GetString(SR.MailHeaderFieldMalformedHeader));
        }

        /*
        // Consider removing.
        internal static string ReadNoFoldLiteral(string data, ref int offset, StringBuilder builder)
        {
            // assume first char is the opening bracket
            int start = ++offset;
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            for (; offset < data.Length; offset++)
            {
                if (data[offset] == '\\')
                {
                    localBuilder.Append(data, start, offset - start);
                    start = ++offset;
                    continue;
                }
                else if (data[offset] == ']')
                {
                    localBuilder.Append(data, start, offset - start);
                    offset++;
                    return (builder != null ? null : localBuilder.ToString());
                }
                else if (data[offset] > s_dtext.Length || !s_dtext[data[offset]])
                {
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                }
            }
            throw new FormatException(SR.GetString(SR.MailHeaderFieldMalformedHeader));
        }
        */


        internal static string ReadAngleAddress(string data, ref int offset, StringBuilder builder)
        {
            if (offset >= data.Length) {
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
            }

            //first, need to get local part
            SkipCFWS(data, ref offset);
            if (data[offset] == '\"') {
                ReadQuotedString(data,ref offset,builder);
            }
            else{
                ReadDotAtom(data, ref offset, builder);
            }

            SkipCFWS(data,ref offset);
            
            if (offset >= data.Length || data[offset] != '@') {
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
            }
            offset++;
            
            SkipCFWS(data,ref offset);

            string address = ReadAddressSpecDomain(data, ref offset, builder);
            if (!SkipCFWS(data, ref offset) || data[offset++] != '>')
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
            return address;
        }


        internal static string ReadAddressSpecDomain(string data,ref int offset, StringBuilder builder){
            if (offset >= data.Length) {
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
            }

            builder.Append('@');
            
            SkipCFWS(data, ref offset);

            if (data[offset] == '['){
                ReadDomainLiteral(data, ref offset, builder);
            }
            else{
                ReadDotAtom(data, ref offset, builder);
            }
            
            SkipCFWS(data, ref offset);

            return builder.ToString();
        }


        internal static string ReadMailAddress(string data, ref int offset, out string displayName){
            string address = null;
            Exception exception = null;
            displayName = String.Empty;
            StringBuilder builder = new StringBuilder();

            try{
                SkipCFWS(data, ref offset);
    
                if (offset >= data.Length) {
                    exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                    goto done;
                }
    
                //angle address
                if (data[offset] == '<')
                {
                    offset++;
                    address = ReadAngleAddress(data, ref offset, builder);
                    return address;
                }
    
    
                //otherwise, its a group, mailbox-name-addr or mailbox-addr-spec
                //get the first part
                //this should skip CFWS internally before and after the phrase
                ReadPhrase(data, ref offset, builder);
    
                if (offset >= data.Length) {
                    exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                    goto done;
                }
    
            // ReadOneOrMoreQuotedStrings() and ReadOneOrMoreDotAtoms() both
            // call SkipCFWS() before they return so the next character should 
            // not be a whitespace character.
            
                switch (data[offset])
                {
                    case '@':{                   
                        //the phrase was the local part
                        offset++;
                        address = ReadAddressSpecDomain(data,ref offset, builder);
                        break;
                    }
                    case '.': {
                        // the phrase was a dotatom, therefore this must be 
                        // the localpart of a mail address or the display name.
                        ReadDotAtom(data, ref offset, builder);
                        SkipCFWS(data, ref offset);
                        
                        if (offset >= data.Length) {
                            exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                            goto done;
                        }
    
                        if (data[offset] == '@') {
                            offset++;
                            address = ReadAddressSpecDomain(data,ref offset,builder);
                        }
                        else if (data[offset] == '<') {
                            displayName = builder.ToString();
                            builder = new StringBuilder();
                            offset++;
                            address = ReadAngleAddress(data, ref offset, builder);
                        }
                        else{
                            exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                            goto done;
                        }
    
                        break;
                    }
                    case '\"':{
                        // the phrase was a quoted string, therefore this must be 
                        // the localpart of a mail address, or the display name.
    
                        //skip whitespace and look at next character
                        offset++;
    
                        if (offset >= data.Length) {
                            exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                            goto done;
                        }
    
                        SkipCFWS(data, ref offset);
    
                        if (offset >= data.Length) {
                            exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                            goto done;
                        }
    
                        //it was the display
                        if (data[offset] == '<') {
                            offset++;
                            address = ReadAngleAddress(data, ref offset, builder);
                        }
                        else{
                            //otherwise, it was the local part
                            address = ReadAddressSpecDomain(data,ref offset,builder);
                        }
                        break;
                    }
                    case '<':{                    
                        //the phrase was a display name
                        displayName = builder.ToString();
                        builder = new StringBuilder();
                        offset++;
                        address = ReadAngleAddress(data, ref offset, builder);
                        break;
                    }
    
                    case ':':{
                        exception = new FormatException(SR.GetString(SR.MailAddressUnsupportedFormat));
                        goto done;
                    }
    
                    default:
                    {
                        exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                        goto done;
                    }
                }
    
                //next character better be whitespace, end of the data, or a comma.  Otherwise, there was an error
                if(offset < data.Length){
                    SkipCFWS(data, ref offset);
                    if(offset < data.Length && data[offset]!=','){
                        exception = new FormatException(SR.GetString(SR.MailAddressInvalidFormat));
                        goto done;
                    }
                }
            }
            catch(FormatException){
                throw new FormatException(SR.GetString(SR.MailAddressInvalidFormat)); 
            }
            
            done:
            if(exception != null){
                throw exception;
            }
            return address;
        }


        internal static MailAddress ReadMailAddress(string data, ref int offset)
        {
            string displayName = null;
            string address = ReadMailAddress(data, ref offset,out displayName);
            return new MailAddress(address,displayName,0);
        }


        /*
        // Consider removing.
        // DATE
        internal static string ReadDigits(string data, ref int offset, StringBuilder builder)
        {
            int start = offset;
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            for (; offset < data.Length && s_digits[data[offset]]; offset++);
            localBuilder.Append(data, start, offset - start);
            return (builder != null ? null : localBuilder.ToString());
        }
        */

        internal static DateTime ReadDateTime(string data, ref int offset)
        {
            if (!SkipCFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            //day of week is optional
            if (IsValidDOW(data, ref offset)){
                if(offset >= data.Length || data[offset] != ',')
                    throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
                offset++;
            }
            
            if (!MailBnfHelper.SkipFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            int day = ReadDateNumber(data, ref offset, 2);

            if (offset >= data.Length || (data[offset] != ' ' && data[offset] != '\t'))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            if (!MailBnfHelper.SkipFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            int month = ReadMonth(data, ref offset);

            if (offset >= data.Length || (data[offset] != ' ' && data[offset] != '\t'))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            if (!MailBnfHelper.SkipFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            int year = ReadDateNumber(data, ref offset, 4);

            if (offset >= data.Length || (data[offset] != ' ' && data[offset] != '\t'))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            if (!MailBnfHelper.SkipFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            int hour = ReadDateNumber(data, ref offset,2);

            if (offset >= data.Length || data[offset] != ':')
                throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
            
            offset++;
            int minute = ReadDateNumber(data, ref offset,2);

            int second = 0;
            if (offset < data.Length && data[offset] == ':')
            {
                offset++;
                second = ReadDateNumber(data, ref offset,2);
            }

            if (!MailBnfHelper.SkipFWS(data, ref offset))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            if (offset >= data.Length || (data[offset] != '-' && data[offset] != '+'))
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            offset++;
            
            int zone = ReadDateNumber(data, ref offset,4);
            // TODO (dougwa): what to do with the zone...

            return new DateTime(year, month, day, hour, minute, second);
        }

        //  date-time       =       [ day-of-week "," ] date FWS time [CFWS]
        //  day-of-week     =       ([FWS] day-name) / obs-day-of-week
        //  day-name        =       "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
        //  date            =       day month year
        //  year            =       4*DIGIT / obs-year
        //  month           =       (FWS month-name FWS) / obs-month
        //  month-name      =       "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
        //  day             =       ([FWS] 1*2DIGIT) / obs-day
        //  time            =       time-of-day FWS zone
        //  time-of-day     =       hour ":" minute [ ":" second ]
        //  hour            =       2DIGIT / obs-hour
        //  minute          =       2DIGIT / obs-minute
        //  second          =       2DIGIT / obs-second
        //  zone            =       (( "+" / "-" ) 4DIGIT) / obs-zone

        static string[] s_months = new string[] { null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        static string[] s_days = new string[] {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
        
        static bool IsValidDOW(string data, ref int offset)
        {
            if(offset + 3 >= data.Length){
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            }
            for(int i = 0; i<s_days.Length;i++){
                if(String.Compare(s_days[i],0,data,offset,3,true, CultureInfo.InvariantCulture) == 0){
                    offset+=3;
                    return true;
                }
            }
            return false;
        }


        static int ReadDateNumber(string data, ref int offset, int maxSize)
        {
            int res = 0;
            int maxLength = offset + maxSize;
            
            if (offset >= data.Length)
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            for (; offset < data.Length && offset < maxLength; offset++)
            {
                if (data[offset] < '0' || data[offset] > '9')
                    break;
                res = (res * 10) + (data[offset] - '0');
            }

            if(res == 0)
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            
            return res;
        }

        static int ReadMonth(string data, ref int offset)
        {
            if (offset >= data.Length - 3)
                throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));

            switch (data[offset++])
            {
                case 'J': case 'j': // jan / jun / jul
                switch (data[offset++])
                {
                    case 'A': case 'a':
                    switch (data[offset++])
                    {
                        case 'N': case 'n': return 1;
                    }
                        break;
                    case 'U': case 'u':
                    switch (data[offset++])
                    {
                        case 'N': case 'n': return 6;
                        case 'L': case 'l': return 7;
                    }
                        break;
                }
                    goto default;
                case 'F': case 'f': // feb
                switch (data[offset++])
                {
                    case 'E': case 'e':
                    switch (data[offset++])
                    {
                        case 'B': case 'b': return 2;
                    }
                        break;
                }
                    goto default;
                case 'M': case 'm': // mar / may
                switch (data[offset++])
                {
                    case 'A': case 'a':
                    switch (data[offset++])
                    {
                        case 'Y': case 'y': return 5;
                        case 'R': case 'r': return 3;
                    }
                        break;
                }
                    goto default;
                case 'A': case 'a': // apr / aug
                switch (data[offset++])
                {
                    case 'P': case 'p':
                    switch (data[offset++])
                    {
                        case 'R': case 'r': return 4;
                    }
                        break;
                    case 'U': case 'u':
                    switch (data[offset++])
                    {
                        case 'G': case 'g': return 8;
                    }
                        break;
                }
                    goto default;
                case 'S': case 's': // sep
                switch (data[offset++])
                {
                    case 'E': case 'e':
                    switch (data[offset++])
                    {
                        case 'P': case 'p': return 9;
                    }
                        break;
                }
                    goto default;
                case 'O': case 'o': // Oct
                switch (data[offset++])
                {
                    case 'C': case 'c':
                    switch (data[offset++])
                    {
                        case 'T': case 't': return 10;
                    }
                        break;
                }
                    goto default;
                case 'N': case 'n': // Nov
                switch (data[offset++])
                {
                    case 'O': case 'o':
                    switch (data[offset++])
                    {
                        case 'V': case 'v': return 11;
                    }
                        break;
                }
                    goto default;
                case 'D': case 'd': // dec
                switch (data[offset++])
                {
                    case 'E':
                    case 'e':
                    switch (data[offset++])
                    {
                        case 'C': case 'c': return 12;
                    }
                        break;
                }
                    goto default;
                default:
                    throw new FormatException(SR.GetString(SR.MailDateInvalidFormat));
            }
        }

        internal static string GetDateTimeString(DateTime value, StringBuilder builder)
        {
            StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
            localBuilder.Append(value.Day);
            localBuilder.Append(' ');
            localBuilder.Append(s_months[value.Month]);
            localBuilder.Append(' ');
            localBuilder.Append(value.Year);
            localBuilder.Append(' ');
            if(value.Hour <= 9){
                localBuilder.Append('0');
            }
            localBuilder.Append(value.Hour);
            localBuilder.Append(':');
            if(value.Minute <= 9){
                localBuilder.Append('0');
            }
            localBuilder.Append(value.Minute);
            localBuilder.Append(':');
            if(value.Second <= 9){
                localBuilder.Append('0');
            }
            localBuilder.Append(value.Second);

            string offset = TimeZone.CurrentTimeZone.GetUtcOffset(value).ToString();
            if (offset[0] != '-') {
                localBuilder.Append(" +");
            }
            else{
                localBuilder.Append(" ");
            }

            string[] offsetFields = offset.Split(':');
            localBuilder.Append(offsetFields[0]);
            localBuilder.Append(offsetFields[1]);
            return (builder != null ? null : localBuilder.ToString());
        }

        internal static string GetTokenOrQuotedString(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_ttext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if (!s_ttext[data[offset]] || data[offset] == ' ')
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('"');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_fqtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_fqtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append('"');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }

            //always a quoted string if it was empty.
            if(data.Length == 0){
                if (builder != null) {
                    builder.Append("\"\"");
                }
                else{
                    return "\"\"";
                }
            }

            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }

        /*
        // Consider removing.
        internal static string GetAtomOrQuotedString(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if (!s_atext[data[offset]] || data[offset] == ' ')
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('"');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_fqtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_fqtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append('"');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }
            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }
        */

        internal static string GetDotAtomOrQuotedString(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if ((data[offset] != '.' && !s_atext[data[offset]]) || data[offset] == ' ')
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('"');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_fqtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_fqtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append('"');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }
            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }

        /*
        internal static string GetDotAtomOrNoFoldQuotedString(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if (data[offset] != '.' && !s_atext[data[offset]])
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('"');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_qtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_qtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append('"');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }
            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }
        */

        /*
        // Consider removing.
        internal static string GetDotAtomOrNoFoldLiteral(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if (data[offset] != '.' && !s_atext[data[offset]])
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('[');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_dtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_dtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append(']');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }
            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }
        */

        internal static string GetDotAtomOrDomainLiteral(string data, StringBuilder builder)
        {
            int offset = 0, start = 0;
            for (; offset < data.Length; offset++)
            {
                if (data[offset] > s_atext.Length)
                    throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));

                if (data[offset] != '.' && !s_atext[data[offset]])
                {
                    StringBuilder localBuilder = (builder != null ? builder : new StringBuilder());
                    builder.Append('[');
                    for (; offset < data.Length; offset++)
                    {
                        if (data[offset] > s_fdtext.Length)
                        {
                            throw new FormatException(SR.GetString(SR.MailHeaderFieldInvalidCharacter));
                        }
                        else if (!s_fdtext[data[offset]])
                        {
                            builder.Append(data, start, offset - start);
                            builder.Append('\\');
                            start = offset;
                        }
                    }
                    builder.Append(data, start, offset - start);
                    builder.Append(']');
                    return (builder != null ? null : localBuilder.ToString());
                }
            }
            if (builder != null)
            {
                builder.Append(data);
                return null;
            }
            return data;
        }

        internal static bool HasCROrLF(string data){
            for (int i=0;i<data.Length;i++) {
                if(data[i] == '\r' || data[i] == '\n'){
                    return true;
                }
            }
            return false;
        }
    }
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1237 on Windows 7 6.1.7100.0>>
AVK Blog
Re[4]: Regex, email address validation
От: cadet354 Россия
Дата: 11.08.09 08:00
Оценка:
Здравствуйте, AndrewVK, Вы писали:


AVK>Видимо потому что некоторые не в курсе, что вместо рефлектора можно использовать сами исходники.

за напоминания про исходники спасибо, но мне не стало понятнее это точно, этакий закат солнца вручную, наверняка быстрее чем regexp на полстраницы, но если надо простое правило как это требовалось автору топика, то ИМНО не подойдет.
P.S. А вообще надо кроме проверки синтаксиса имени почты надо еще отправлять запрос на сервер, а есть ли такой ящик вообще там.
... << RSDN@Home 1.2.0 alpha 4 rev. 1231>>
Re[5]: Regex, email address validation
От: _FRED_ Черногория
Дата: 11.08.09 08:17
Оценка:
Здравствуйте, cadet354, Вы писали:

AVK>>Видимо потому что некоторые не в курсе, что вместо рефлектора можно использовать сами исходники.

C>за напоминания про исходники спасибо, но мне не стало понятнее это точно, этакий закат солнца вручную,

А зачем "понимать"? Взял и заиспользовал у себя

C>наверняка быстрее чем regexp на полстраницы, но если надо простое правило как это требовалось автору топика, то ИМНО не подойдет.


Вряд ли автору есть разница: напишет он один регекс или добавит отдельный файл и опять же на вызов понадобится одна строка.

C>P.S. А вообще надо кроме проверки синтаксиса имени почты надо еще отправлять запрос на сервер, а есть ли такой ящик вообще там.


Что значит "надо"? Кому "надо"? Топикстартеру точно не "надо" (не просил), да и не один вменяемый почтовый клиент этого не делает. Если что не так — сервер пришлёт соответствующий ответ в соответствии со своими настройками.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Regex, email address validation
От: whatever  
Дата: 11.08.09 13:23
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, cadet354, Вы писали:


AVK>>>Видимо потому что некоторые не в курсе, что вместо рефлектора можно использовать сами исходники.

C>>за напоминания про исходники спасибо, но мне не стало понятнее это точно, этакий закат солнца вручную,

_FR>А зачем "понимать"? Взял и заиспользовал у себя


Там даже на первый взгляд есть ненужный для моей задачи код.

C>>наверняка быстрее чем regexp на полстраницы, но если надо простое правило как это требовалось автору топика, то ИМНО не подойдет.


_FR>Вряд ли автору есть разница: напишет он один регекс или добавит отдельный файл и опять же на вызов понадобится одна строка.


Мне психологически сложно для того, чтобы выделить красным цветом опечатку юзера в поле ввода, добавлять такой большой класс, с кучей ненужного кода, изобилующего операторами goto. Если бы этот класс был объявлен как public — тогда другое дело.

C>>P.S. А вообще надо кроме проверки синтаксиса имени почты надо еще отправлять запрос на сервер, а есть ли такой ящик вообще там.


_FR>Что значит "надо"? Кому "надо"? Топикстартеру точно не "надо" (не просил), да и не один вменяемый почтовый клиент этого не делает. Если что не так — сервер пришлёт соответствующий ответ в соответствии со своими настройками.


Потратил немного времени на ознакомление с рег. выражениями, результат теперь такой:
return System.Text.RegularExpressions.Regex.IsMatch(address, @"(?i)^([a-z0-9]([a-z\.0-9-_]*[a-z0-9])*@([a-z0-9][a-z0-9\.-]*[a-z0-9]\.)+[a-z]{2,9})$");
Re[2]: Regex, email address validation
От: whatever  
Дата: 11.08.09 13:26
Оценка:
Здравствуйте, Warturtle, Вы писали:
...
W>зацени

Удивило... обойдусь чем-нибудь попроще
Re[6]: Regex, email address validation
От: cadet354 Россия
Дата: 12.08.09 05:38
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>А зачем "понимать"? Взял и заиспользовал у себя

топикстартер ответил уже на предложение использовать этот метод

_FR>Что значит "надо"? Кому "надо"? Топикстартеру точно не "надо" (не просил), да и не один вменяемый почтовый клиент этого не делает. Если что не так — сервер пришлёт соответствующий ответ в соответствии со своими настройками.

причем тут почтовый клиент , я сам встречался с ситуациями когда указывал левый адрес (намеренно или опечатывался) и мне на это указывалось, а синтаксически все было верно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1231>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.