(编辑:什么是Code Golf: Code Golf是解决特定问题的挑战,使用您喜欢的任何语言中的字符数最少的代码。 More info here在Meta StackOverflow上。)
Code Golfers,这是对字符串操作的挑战。
电子邮件地址验证,但没有正则表达式(或类似的解析库)当然。它不是关于电子邮件地址,而是你可以写下下面给出的不同字符串操作和约束的时间。
规则如下(是的,我知道,这不符合RFC,但这些将成为此挑战的5条规则):
在@:
之前,该组中至少有一个字符A-Z, a-z, 0-9, . (period), _ (underscore)
@必须存在,恰好一次
john@smith.com
^
句号(。)必须在@
后恰好存在一次john@smith.com
^
@和以下之间至少有1个 [A-Z,a-z] 字符。 (周期)
john@s.com
^
决赛后至少2个 [A-Z,a-z] 个字符。期
john@smith.ab
^^
请仅发布方法/函数,这将采用字符串(建议的电子邮件地址),然后返回布尔结果(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)
祝你好运!
答案 0 :(得分:20)
#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!");
}
答案 1 :(得分:12)
:[[/%^(:[[+-/^,&i|:[$[' ']^j+0__:k<3:]]
答案 2 :(得分:6)
#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()
,因此我觉得这个答案不像strager的答案那样“干净”,没有任何库函数。 (我也偷了他一个没有类型声明全局变量的想法!)
这里的一个技巧是,将.
和_
放在字符串A
的开头,可以在strspn()
中轻松地包含或排除它们测试:当你想允许它们时,使用strspn(something, A)
;如果不这样做,请使用strspn(something, A+12)
。另一个是假设sizeof (short) == 2 * sizeof (char)
,并且一次从“种子”对Aa
构建有效字符数组2。其余的只是寻找一种方法来强制子表达式看起来足够相似,以便可以将它们拉出#define
d宏。
要使此代码更“可移植”(呵呵:-P),您可以从
更改数组构建代码char A[66]="_.0123456789Aa";short*s=A+12;for(;++s<A+64;)*s=s[-1]+257;
到
char*A="_.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
需要额外支付5个字符。
答案 3 :(得分: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]
基本上只是一个使用混淆的短变量名的状态机。
答案 4 :(得分:5)
#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 :(得分:4)
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
测试用例,借鉴strager's answer:
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
在“okay”中以1
开头,即为true,并且一旦发现在当前状态下非法的字符,则设置为0
。
法律人物是:
0
:字母,数字,下划线,句号(在任何情况下将状态更改为1
)1
:字母,数字,下划线,句号,符号(如果找到“2
”,则将状态更改为@
)2
:字母(将状态更改为3
)3
:字母,句点(如果找到句点,则将状态更改为4)4
至6
:字母(4
或5
时的增量状态)当我们一直走过字符串时,我们会返回t==6
(t>5
是否少一个字符)且o
是否为1。
答案 6 :(得分: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;
}
答案 7 :(得分:2)
毫无疑问,这不是最好的解决方案,而且相当冗长,但它是有效的。
已修复(所有测试用例现已通过)
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;
}
答案 8 :(得分:2)
#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;
}
仍然是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绝对令人作呕!
测试我的第一个(错误)版本。
答案 9 :(得分:1)
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;}
通过所有测试(我的旧版本不正确)。
答案 10 :(得分:1)
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
答案 11 :(得分:1)
Erlang 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.
答案 12 :(得分:1)
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
答案 13 :(得分:1)
'不使用正则表达式': PHP 47 Chars。
<?=filter_var($argv[1],FILTER_VALIDATE_EMAIL);
答案 14 :(得分:1)
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"
]