Гольф кода: проверка адреса электронной почты без регулярных выражений

Я соглашаюсь. Проблемами с триггерами являются люди, не триггеры. Хотя это больше, чтобы посмотреть на, больше рассмотреть и увеличивает бремя на кодерах, проверяющих вещи правильно, мы не отбрасываем индексы для создания наших жизней более простыми. (Плохие индексы могут быть настолько же плохими как плохие триггеры)

, важность триггеров (в моем уме) является этим...
- Любая система должна всегда быть в допустимом состоянии
- Код для осуществления этого допустимого состояния должен быть централизован (не записанный в каждом SP)

С точки зрения обслуживания, триггер очень полезен для компетентных кодеров и проблем для более младших/любительских. Все же эти люди должны учиться и вырасти так или иначе.

я предполагаю, что это сводится к Вашей рабочей среде. У Вас есть надежные люди, которые учатся хорошо и могут доверяться, чтобы быть методическими? Если не у Вас по-видимому есть два варианта:
- Признают, что необходимо будет проиграть, функциональность для компенсации
- Признают, что Вам нужны различные люди или лучшее обучение и управление

, Они звучат резкими, и я предполагаю, что они. Но это - основная истина в моем уме...

17
задан 7 revs, 2 users 66% 20 March 2017 в 10:29
поделиться

15 ответов

Ruby , 225 символов . Это моя первая программа на Ruby, так что она, вероятно, не очень похожа на Ruby: -)

def v z;r=!a=b=c=d=e=f=0;z.chars{|x|case x when'@';r||=b<1||!e;e=!1 when'.'
e ?b+=1:(a+=1;f=e);r||=a>1||(c<1&&!e)when'0'..'9';b+=1;r|=!e when'A'..'Z','a'..'z'
e ?b+=1:f ?c+=1:d+=1;else r=1 if x!='_'||!e|!b+=1;end};!r&&d>1 end
1
ответ дан 30 November 2019 в 10:13
поделиться

Эрланг 266 символов:

-module(cg_email).

-export([test/0]).

%%% golf code begin %%%
-define(E,when X>=$a,X=<$z;X>=$A,X=<$Z).
-define(I(Y,Z),Y([X|L])?E->Z(L);Y(_)->false).
-define(L(Y,Z),Y([X|L])?E;X>=$0,X=<$9;X=:=$.;X=:=$_->Z(L);Y(_)->false).
?L(e,m).
m([$@|L])->a(L);?L(m,m).
?I(a,i).
i([$.|L])->l(L);?I(i,i).
?I(l,c).
?I(c,g).
g([])->true;?I(g,g).
%%% golf code end %%%

test() ->
  true  = e("b@w.org"),
  false = e("b@c@d.org"),
  false = e("test@%.org"),
  false = e("j_r@x.c.il"),
  true  = e("r..t@x.tw"),
  false = e("test@org"),
  false = e("s%p@m.org"),
  true  = e("j_r@x.mil"),
  false = e("foo@a%.com"),
  ok.
1
ответ дан 30 November 2019 в 10:13
поделиться

Java : 257 символов (не включая 3 конца строки для удобочитаемости; -)).

boolean q(char[]s){int a=0,b=0,c=0,d=0,e=0,f=0,g,y=-99;for(int i:s)
d=(g="@._0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm".indexOf(i))<0?
y:g<1&&++e>0&(b<1|++a>1)?y:g==1&e>0&(c<1||f++>0)?y:++b>0&g>12?f>0?d+1:f<1&e>0&&++c>0?
d:d:d;return d>1;}

Проходит все тесты (моя старая версия была неверно).

1
ответ дан 30 November 2019 в 10:13
поделиться

VBA / VB6 - 484 символа

Явное отключение
использование: VE (" b@w.org ")

Function V(S, C)
V = True
For I = 1 To Len(S)
 If InStr(C, Mid(S, I, 1)) = 0 Then
  V = False: Exit For
 End If
Next
End Function

Function VE(E)
VE = False
C1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHILKLMNOPQRSTUVWXYZ"
C2 = "0123456789._"
P = Split(E, "@")
If UBound(P) <> 1 Then GoTo X
If Len(P(0)) < 1 Or Not V(P(0), C1 & C2) Then GoTo X
E = P(1): P = Split(E, ".")
If UBound(P) <> 1 Then GoTo X
If Len(P(0)) < 1 Or Not V(P(0), C1) Or Len(P(1)) < 2 Or Not V(P(1), C1) Then GoTo X
VE = True
X:
End Function
1
ответ дан 30 November 2019 в 10:13
поделиться

Какую бы версию C ++ ни поддерживал MSVC2008.

Вот мое скромное представление. Теперь я знаю, почему мне сказали никогда не делать того, что я делал здесь:

#define N return 0
#define I(x) &&*x!='.'&&*x!='_'
bool p(char*a) {
 if(!isalnum(a[0])I(a))N;
 char*p=a,*b=0,*c=0;
 for(int d=0,e=0;*p;p++){
  if(*p=='@'){d++;b=p;}
  else if(*p=='.'){if(d){e++;c=p;}}
  else if(!isalnum(*p)I(p))N;
  if (d>1||e>1)N;
 }
 if(b>c||b+1>=c||c+2>=p)N;
 return 1;
}
2
ответ дан 30 November 2019 в 10:13
поделиться

C (166 символов )

#define F(t,u)for(r=s;t=(*s-64?*s-46?isalpha(*s)?3:isdigit(*s)|*s==95?4:0:2:1);++s);if(s-r-1 u)return 0;
V(char*s){char*r;F(2<,<0)F(1=)F(3=,<0)F(2=)F(3=,<1)return 1;}

Требуется одна новая строка, и я посчитал ее как один символ.

5
ответ дан 30 November 2019 в 10:13
поделиться

C89, 175 символов.

#define G &&*((a+=t+1)-1)==
#define H (t=strspn(a,A
t;e(char*a){char A[66]="_.0123456789Aa";short*s=A+12;for(;++s<A+64;)*s=s[-1]+257;return H))G 64&&H+12))G 46&&H+12))>1 G 0;}

Я использую стандартную библиотечную функцию strspn () , поэтому мне кажется, что этот ответ не такой «чистый», как ответ незнакомца что делает без каких-либо библиотечных функций. (Я также украл у него идею объявления глобальной переменной без типа!)

Один из приемов здесь заключается в том, чтобы поставить . и _ в начале строки A , их можно легко включить или исключить в тесте strspn () : когда вы хотите их разрешить, используйте strspn (что-то, A) ; в противном случае используйте strspn (something, A + 12) . Другой предполагает, что sizeof (short) == 2 * sizeof (char) , и создает массив допустимых символов по 2 за раз из "seed" пара Aa . Остальные просто искали способ заставить подвыражения выглядеть достаточно похожими, чтобы их можно было вытащить в макрос #define d.

Чтобы сделать этот код более «переносимым» (heh :-P) вы можете изменить код построения массива с

char A[66]="_.0123456789Aa";short*s=A+12;for(;++s<A+64;)*s=s[-1]+257;

на

char*A="_.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

за 5 дополнительных символов.

6
ответ дан 30 November 2019 в 10:13
поделиться

J

:[[/%^(:[[+-/^,&i|:[$[' ']^j+0__:k<3:]]
12
ответ дан 30 November 2019 в 10:13
поделиться

C89 (166 символов)

#define B(c)isalnum(c)|c==46|c==95
#define C(x)if(!v|*i++-x)return!1;
#define D(x)for(v=0;x(*i);++i)++v;
v;e(char*i){D(B)C(64)D(isalpha)C(46)D(isalpha)return!*i&v>1;}

Не повторяется, но может выполняться несколько раз. Стенд:

#include<stdio.h>
#include<assert.h>
main(){
    assert(e("b@w.org"));
    assert(e("r..t@x.tw"));
    assert(e("j_r@x.mil"));
    assert(!e("b@c@d.org"));
    assert(!e("test@%.org"));
    assert(!e("j_r@x.c.il"));
    assert(!e("@w.org"));
    assert(!e("test@org"));
    assert(!e("s%p@m.org"));
    assert(!e("foo@a%.com"));
    puts("success!");
}
20
ответ дан 30 November 2019 в 10:13
поделиться

Не зависит от набора символов C89 (262 символа)

#include <stdio.h>

/* the 'const ' qualifiers should be removed when */
/* counting characters: I don't like warnings :) */
/* also the 'int ' should not be counted. */

/* it needs only 2 spaces (after the returns), should be only 2 lines */
/* that's a total of 262 characters (1 newline, 2 spaces) */

/* code golf starts here */

#include<string.h>
int v(const char*e){
const char*s="0123456789._abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(e=strpbrk(e,s))
  if(e=strchr(e+1,'@'))
    if(!strchr(e+1,'@'))
      if(e=strpbrk(e+1,s+12))
        if(e=strchr(e+1,'.'))
          if(!strchr(e+1,'.'))
            if(strlen(e+1)>1)
              return 1;
return 0;
}

/* code golf ends here */

int main(void) {
  const char *t;
  t = "b@w.org"; printf("%s ==> %d\n", t, v(t));
  t = "r..t@x.tw"; printf("%s ==> %d\n", t, v(t));
  t = "j_r@x.mil"; printf("%s ==> %d\n", t, v(t));
  t = "b@c@d.org"; printf("%s ==> %d\n", t, v(t));
  t = "test@%.org"; printf("%s ==> %d\n", t, v(t));
  t = "j_r@x.c.il"; printf("%s ==> %d\n", t, v(t));
  t = "@w.org"; printf("%s ==> %d\n", t, v(t));
  t = "test@org"; printf("%s ==> %d\n", t, v(t));
  t = "s%p@m.org"; printf("%s ==> %d\n", t, v(t));
  t = "foo@a%.com"; printf("%s ==> %d\n", t, v(t));

  return 0;
}

Версия 2

По-прежнему не зависит от набора символов C89, ошибки, надеюсь, исправлены (303 символа; 284 без #include)

#include<string.h>
#define Y strchr
#define X{while(Y
v(char*e){char*s="0123456789_.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(*e!='@')X(s,*e))e++;if(*e++=='@'&&!Y(e,'@')&&Y(e+1,'.'))X(s+12,*e))e++;if(*e++=='.'
&&!Y(e,'.')&&strlen(e)>1){while(*e&&Y(s+12,*e++));if(!*e)return 1;}}}return 0;}

Этот # define X абсолютно отвратителен!

Протестируйте мою первую (глючную) версию.

2
ответ дан 30 November 2019 в 10:13
поделиться

Python, 149 символов (после помещения всего цикла for в одну строку, разделенную точкой с запятой, что я не делал здесь для "удобочитаемости") :

def v(s,t=0,o=1):
 for c in s:
   k=c=="@"
   p=c=="."
   A=c.isalnum()|p|(c=="_")
   L=c.isalpha()
   o&=[A,k|A,L,L|p,L,L,L][t]
   t+=[1,k,1,p,1,1,0][t]
 return(t>5)&o

Контрольные примеры , заимствованы из ответа незнакомца :

assert v("b@w.org")
assert v("r..t@x.tw")
assert v("j_r@x.mil")
assert not v("b@c@d.org")
assert not v("test@%.org")
assert not v("j_r@x.c.il")
assert not v("@w.org")
assert not v("test@org")
assert not v("s%p@m.org")
assert not v("foo@a%.com")
print "Yeah!"

Объяснение : При итерации по строке две переменные продолжают обновляться.

t сохраняет текущее состояние:

  • t = 0 : мы в начале.
  • t = 1 : мы были в начале и нашли хотя бы один допустимый символ (буква, число, подчеркивание, период)
  • t = 2 : мы нашли " @ "
  • t = 3 : мы обнаружили, по крайней мере, юридический символ (т.е. букву) после " @ "
  • t = 4 :Мы нашли точку в доменном имени
  • t = 5 : Мы нашли один допустимый символ (букву) после точки
  • t = 6 : Мы нашли как минимум два допустимых символа после период

o , как в «хорошо», начинается с 1 , то есть истина, и устанавливается в 0 , как только обнаруживается недопустимый символ в Текущее состояние. Допустимые символы:

  • В состоянии 0 : буква, число, подчеркивание, точка (в любом случае измените состояние на 1 )
  • В состоянии 1 : буква, число, подчеркивание, точка, знак (измените состояние на 2 , если найдено « @ »)
  • В состоянии 2 : буква (изменить состояние на 3 )
  • В состоянии 3 : буква, период (изменить состояние на 4, если период найден)
  • В состояниях 4 thru 6 : letter (состояние приращения, когда в 4 или 5 )

Когда мы прошли весь путь по строке, мы возвращаем, t == 6 ( t> 5 на один символ меньше) и o равно 1.

4
ответ дан 30 November 2019 в 10:13
поделиться

Python (181 символ, включая символы новой строки)

def v(E):
 import string as t;a=t.ascii_letters;e=a+"1234567890_.";t=e,e,"@",e,".",a,a,a,a,a,"",a
 for c in E:
  if c in t[0]:t=t[2:]
  elif not c in t[1]:return 0>1
 return""==t[0]

По сути, это всего лишь конечный автомат, использующий непонятно короткие имена переменных.

5
ответ дан 30 November 2019 в 10:13
поделиться

Без сомнения, не самое лучшее решение и чертовски многословно, но оно действительно.

Исправлено (Все тестовые примеры успешно пройдены)

    static bool ValidateEmail(string email)
{
    var numbers = "1234567890";
    var uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var lowercase = uppercase.ToLower();
    var arUppercase = uppercase.ToCharArray();
    var arLowercase = lowercase.ToCharArray();
    var arNumbers = numbers.ToCharArray();
    var atPieces = email.Split(new string[] { "@"}, StringSplitOptions.RemoveEmptyEntries);
    if (atPieces.Length != 2)
        return false;
    foreach (var c in atPieces[0])
    {
        if (!(arNumbers.Contains(c) || arLowercase.Contains(c) || arUppercase.Contains(c) || c == '.' || c == '_'))
            return false;
    }
    if(!atPieces[1].Contains("."))
        return false;
    var dotPieces = atPieces[1].Split('.');
    if (dotPieces.Length != 2)
        return false;
    foreach (var c in dotPieces[0])
    {
        if (!(arLowercase.Contains(c) || arUppercase.Contains(c)))
            return false;
    }
    var found = 0;
    foreach (var c in dotPieces[1])
    {
        if ((arLowercase.Contains(c) || arUppercase.Contains(c)))
            found++;
        else
            return false;
    }
    return found >= 2;
}
2
ответ дан 30 November 2019 в 10:13
поделиться

Haskell (GHC 6.8.2), 165 161 144C Символы


Использование сопоставления с образцом, elem , span и all :

a=['A'..'Z']++['a'..'z']
e=f.span(`elem`"._0123456789"++a)
f(_:_,'@':d)=g$span(`elem`a)d
f _=False
g(_:_,'.':t@(_:_:_))=all(`elem`a)t
g _=False

Вышеупомянутое было проверено с помощью следующего кода:

main :: IO ()
main = print $ and [
  e "b@w.org",
  e "r..t@x.tw",
  e "j_r@x.mil",
  not $ e "b@c@d.org",
  not $ e "test@%.org",
  not $ e "j_r@x.c.il",
  not $ e "@w.org",
  not $ e "test@org",
  not $ e "s%p@m.org",
  not $ e "foo@a%.com"
  ]
1
ответ дан 30 November 2019 в 10:13
поделиться

'Не использовать регулярное выражение': PHP 47 символов.

<?=filter_var($argv[1],FILTER_VALIDATE_EMAIL);
1
ответ дан 30 November 2019 в 10:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: