Code Golf:没有正则表达式的电子邮件地址验证

Ale*_*lex 17 code-golf rosetta-stone

(编辑:什么是Code Golf:Code Golf是用你喜欢的任何语言按字符数最短的代码解决特定问题的挑战. 更多关于Meta StackOverflow的信息.)

Code Golfers,这是对字符串操作的挑战.

电子邮件地址验证,但当然没有正则表达式(或类似的解析库).这不是关于电子邮件地址,而是你可以写下下面给出的不同字符串操作和约束的时间.

规则如下(是的,我知道,这不符合RFC,但这些将成为此挑战的5条规则):

请发布方法/函数,这将采用字符串(建议的电子邮件地址),然后返回布尔结果(true/false),具体取决于有效的电子邮件地址(true)或无效(false).

Samples:
b@w.org    (valid/true)          @w.org     (invalid/false)    
b@c@d.org  (invalid/false)       test@org   (invalid/false)    
test@%.org (invalid/false)       s%p@m.org  (invalid/false)    
j_r@x.c.il (invalid/false)       j_r@x.mil  (valid/true)
r..t@x.tw  (valid/true)          foo@a%.com (invalid/false)
Run Code Online (Sandbox Code Playgroud)

祝好运!

str*_*ger 20

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;}
Run Code Online (Sandbox Code Playgroud)

不可重入,但可以多次运行.试验台:

#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!");
}
Run Code Online (Sandbox Code Playgroud)

  • @strager:`isalpha()`比`c <91&c> 64 | c <123&c> 96`短得多,并且没有`#include`.事实上,那么你只需要`#define A isalpha`.嗯......想想看,只要你现在使用`A`就可以使用`isalpha`,并将`#define A`全部放在一起. (2认同)

P D*_*ddy 12

Ĵ

:[[/%^(:[[+-/^,&i|:[$[' ']^j+0__:k<3:]]
Run Code Online (Sandbox Code Playgroud)

  • 一开始会让人感到非常难过,但到最后它会变得非常开心. (36认同)

j_r*_*ker 6

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;}
Run Code Online (Sandbox Code Playgroud)

我正在使用标准库函数strspn(),所以我觉得这个答案不像strager的答案那样"干净",没有任何库函数.(我也偷了他一个没有类型声明全局变量的想法!)

这里的一个技巧是通过放置._开始字符串A,可以在strspn()测试中轻松地包含或排除它们:当你想要允许它们时,使用strspn(something, A); 如果你不这样做,请使用strspn(something, A+12).另一个是假设sizeof (short) == 2 * sizeof (char),并且从"种子"对一次建立有效字符2的数组Aa.其余的只是寻找一种方法来强制子表达式看起来足够相似,以便它们可以被拉出到#defined宏中.

为了使这个代码更"可移植"(heh :-P),你可以改变数组构建代码

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

char*A="_.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Run Code Online (Sandbox Code Playgroud)

额外费用为5个字符.

  • 我认为应该包含`#include <string.h>`.否则,它不便携.(你的`short`东西也不便携,但至少你提供了一个便宜的替代品.) (3认同)
  • `size_t strspn();`字符比`#include`少,并且可以完成工作(也不需要换行). (2认同)

Sea*_*ean 5

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]
Run Code Online (Sandbox Code Playgroud)

基本上只是一个使用混淆的短变量名称的状态机.


P D*_*ddy 5

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;}
Run Code Online (Sandbox Code Playgroud)

单个换行是必需的,我把它算作一个字符.


i_a*_*orf 2

MSVC2008 支持的任何 C++ 版本。

这是我的谦卑的提交。现在我知道为什么他们告诉我永远不要做我在这里所做的事情:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 最好在您的答案中提供字符数以及所使用的语言。 (4认同)