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

发布于 2024-08-03 21:37:04 字数 2427 浏览 8 评论 0原文

(编辑:什么是 Code Golf:Code Golf 是一种以最短的代码量(按您喜欢的语言的字符数)解决特定问题的挑战。 有关 Meta StackOverflow 的更多信息。)

代码高尔夫球手,这里有一个关于字符串操作的挑战。

电子邮件地址验证,但当然没有正则表达式(或类似的解析库)。重要的不是电子邮件地址,而是您可以编写下面给出的不同字符串操作和约束的长度。

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

请仅发布方法/函数,该方法/函数将采用字符串(建议的电子邮件地址),然后根据电子邮件地址有效(真)或无效(假)返回布尔结果(真/假)。< /strong>

Samples:
[email protected]    (valid/true)          @w.org     (invalid/false)    
b@[email protected]  (invalid/false)       test@org   (invalid/false)    
test@%.org (invalid/false)       s%[email protected]  (invalid/false)    
[email protected] (invalid/false)       [email protected]  (valid/true)
[email protected]  (valid/true)          foo@a%.com (invalid/false)

祝你好运!

(Edit: What is Code Golf: Code Golf are challenges to solve a specific problem with the shortest amount of code by character count in whichever language you prefer. More info here on Meta StackOverflow. )

Code Golfers, here's a challenge on string operations.

Email Address Validation, but without regular expressions (or similar parsing library) of course. It's not so much about the email addresses but how short you can write the different string operations and constraints given below.

The rules are the following (yes, I know, this is not RFC compliant, but these are going to be the 5 rules for this challenge):

  • At least 1 character out of this group before the @:

    A-Z, a-z, 0-9, . (period), _ (underscore)
    
  • @ has to exist, exactly one time

    [email protected]
        ^
    
  • Period (.) has to exist exactly one time after the @

    [email protected]
              ^
    
  • At least 1 only [A-Z, a-z] character between @ and the following . (period)

    [email protected]
         ^
    
  • At least 2 only [A-Z, a-z] characters after the final . period

    [email protected]
               ^^
    

Please post the method/function only, which would take a string (proposed email address) and then return a Boolean result (true/false) depending on the email address being valid (true) or invalid (false).

Samples:
[email protected]    (valid/true)          @w.org     (invalid/false)    
b@[email protected]  (invalid/false)       test@org   (invalid/false)    
test@%.org (invalid/false)       s%[email protected]  (invalid/false)    
[email protected] (invalid/false)       [email protected]  (valid/true)
[email protected]  (valid/true)          foo@a%.com (invalid/false)

Good luck!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

掀纱窥君容 2024-08-10 21:37:04

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("[email protected]"));
    assert(e("[email protected]"));
    assert(e("[email protected]"));
    assert(!e("b@[email protected]"));
    assert(!e("test@%.org"));
    assert(!e("[email protected]"));
    assert(!e("@w.org"));
    assert(!e("test@org"));
    assert(!e("s%[email protected]"));
    assert(!e("foo@a%.com"));
    puts("success!");
}

C89 (166 characters)

#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;}

Not re-entrant, but can be run multiple times. Test bed:

#include<stdio.h>
#include<assert.h>
main(){
    assert(e("[email protected]"));
    assert(e("[email protected]"));
    assert(e("[email protected]"));
    assert(!e("b@[email protected]"));
    assert(!e("test@%.org"));
    assert(!e("[email protected]"));
    assert(!e("@w.org"));
    assert(!e("test@org"));
    assert(!e("s%[email protected]"));
    assert(!e("foo@a%.com"));
    puts("success!");
}
想挽留 2024-08-10 21:37:04

J

:[[/%^(:[[+-/^,&i|:[$[' ']^j+0__:k<3:]]

J

:[[/%^(:[[+-/^,&i|:[$[' ']^j+0__:k<3:]]
最单纯的乌龟 2024-08-10 21:37:04

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(),所以我觉得这个答案不像 strager 的答案那么“干净”,它没有任何库函数。 (我还窃取了他声明不带类型的全局变量的想法!)

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

为了使此代码更“可移植”(heh :-P),您可以将数组构建代码从 更改为 ,但

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

需要

char*A="_.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

额外增加 5 个字符。

C89, 175 characters.

#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;}

I am using the standard library function strspn(), so I feel this answer isn't as "clean" as strager's answer which does without any library functions. (I also stole his idea of declaring a global variable without a type!)

One of the tricks here is that by putting . and _ at the start of the string A, it's possible to include or exclude them easily in a strspn() test: when you want to allow them, use strspn(something, A); when you don't, use strspn(something, A+12). Another is assuming that sizeof (short) == 2 * sizeof (char), and building up the array of valid characters 2 at a time from the "seed" pair Aa. The rest was just looking for a way to force subexpressions to look similar enough that they could be pulled out into #defined macros.

To make this code more "portable" (heh :-P) you can change the array-building code from

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

to

char*A="_.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

for a cost of 5 additional characters.

冷夜 2024-08-10 21:37:04

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]

基本上只是一个使用令人困惑的短变量名的状态机。

Python (181 characters including newlines)

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]

Basically just a state machine using obfuscatingly short variable names.

黯然 2024-08-10 21:37:04

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;}

需要单个换行符,我将其算作一个字符。

C (166 characters)

#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;}

The single newline is required, and I've counted it as one character.

无语# 2024-08-10 21:37:04

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的答案:

assert v("[email protected]")
assert v("[email protected]")
assert v("[email protected]")
assert not v("b@[email protected]")
assert not v("test@%.org")
assert not v("[email protected]")
assert not v("@w.org")
assert not v("test@org")
assert not v("s%[email protected]")
assert not v("foo@a%.com")
print "Yeah!"

解释:迭代字符串时,两个变量不断更新。

t 保持当前状态:

  • t = 0:我们正处于开始阶段。
  • t = 1:我们从一开始就找到了至少一个合法字符(字母、数字、下划线、句点)
  • t = 2:我们找到了“< code>@"
  • t = 3:我们在“@”之后至少找到了一个合法字符(即字母)
  • t = 4< /code>:我们在域名中找到了句点
  • t = 5:我们在句点后面找到了一个合法字符(字母)
  • t = 6:我们发现句号 o 后至少有两个合法字符,

如“okay”,以 1 开头,即 true,并且一旦满足就会设置为 0发现一个字符在当前状态下是非法的。
合法字符为:

  • 在状态 0 下:字母、数字、下划线、句点(在任何情况下将状态更改为 1
  • 在状态 1 下:字母、数字、下划线、句点、at 符号(如果找到“@”,则将状态更改为 2
  • 在状态 2 中:字母(更改状态到 3)
  • 在状态 3 中:字母、句点(如果找到句点,则将状态更改为 4)
  • 在状态 46< /code>:字母(在 45 时递增状态)

当我们遍历完字符串后,我们返回是否 t==6< /code>(t>5 少一个字符),o 为 1。

Python, 149 chars (after putting the whole for loop into one semicolon-separated line, which I haven't done here for "readability" purposes):

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

Test cases, borrowed from strager's answer:

assert v("[email protected]")
assert v("[email protected]")
assert v("[email protected]")
assert not v("b@[email protected]")
assert not v("test@%.org")
assert not v("[email protected]")
assert not v("@w.org")
assert not v("test@org")
assert not v("s%[email protected]")
assert not v("foo@a%.com")
print "Yeah!"

Explanation: When iterating over the string, two variables keep getting updated.

t keeps the current state:

  • t = 0: We're at the beginning.
  • t = 1: We where at the beginning and have found at least one legal character (letter, number, underscore, period)
  • t = 2: We have found the "@"
  • t = 3: We have found at least on legal character (i.e. letter) after the "@"
  • t = 4: We have found the period in the domain name
  • t = 5: We have found one legal character (letter) after the period
  • t = 6: We have found at least two legal characters after the period

o as in "okay" starts as 1, i.e. true, and is set to 0 as soon as a character is found that is illegal in the current state.
Legal characters are:

  • In state 0: letter, number, underscore, period (change state to 1 in any case)
  • In state 1: letter, number, underscore, period, at-sign (change state to 2 if "@" is found)
  • In state 2: letter (change state to 3)
  • In state 3: letter, period (change state to 4 if period found)
  • In states 4 thru 6: letter (increment state when in 4 or 5)

When we have gone all the way through the string, we return whether t==6 (t>5 is one char less) and o is 1.

蓝海似她心 2024-08-10 21:37:04

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;
}

Whatever version of C++ MSVC2008 supports.

Here's my humble submission. Now I know why they told me never to do the things I did in here:

#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;
}
眼睛会笑 2024-08-10 21:37:04

毫无疑问,这不是最好的解决方案,而且相当冗长,但它是有效的。

已修复(所有测试用例现已通过)

    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;
}

Not the greatest solution no doubt, and pretty darn verbose, but it is valid.

Fixed (All test cases pass now)

    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;
}
北方。的韩爷 2024-08-10 21:37:04

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 = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "b@[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "test@%.org"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; 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%[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "foo@a%.com"; printf("%s ==> %d\n", t, v(t));

  return 0;
}

版本 2

仍然是 C89 字符集不可知,希望纠正错误(303 个字符;没有 #include 的 284 个字符)

#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 绝对令人恶心!

测试我的第一个(有缺陷的)版本。

C89 character set agnostic (262 characters)

#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 = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "b@[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "test@%.org"; printf("%s ==> %d\n", t, v(t));
  t = "[email protected]"; 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%[email protected]"; printf("%s ==> %d\n", t, v(t));
  t = "foo@a%.com"; printf("%s ==> %d\n", t, v(t));

  return 0;
}

Version 2

Still C89 character set agnostic, bugs hopefully corrected (303 chars; 284 without the #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;}

That #define X is absolutely disgusting!

Test as for my first (buggy) version.

无声情话 2024-08-10 21:37:04

VBA/VB6 - 484 个字符

显式关闭
用法:VE("[电子邮件受保护]")

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

VBA/VB6 - 484 chars

Explicit off
usage: VE("[email protected]")

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
等风也等你 2024-08-10 21:37:04

Java257 个字符(不包括 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;}

通过所有测试(我的旧版本不正确)。

Java: 257 chars (not including the 3 end of lines for readability ;-)).

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;}

Passes all the tests (my older version was incorrect).

司马昭之心 2024-08-10 21:37:04

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("[email protected]"),
  false = e("b@[email protected]"),
  false = e("test@%.org"),
  false = e("[email protected]"),
  true  = e("[email protected]"),
  false = e("test@org"),
  false = e("s%[email protected]"),
  true  = e("[email protected]"),
  false = e("foo@a%.com"),
  ok.

Erlang 266 chars:

-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("[email protected]"),
  false = e("b@[email protected]"),
  false = e("test@%.org"),
  false = e("[email protected]"),
  true  = e("[email protected]"),
  false = e("test@org"),
  false = e("s%[email protected]"),
  true  = e("[email protected]"),
  false = e("foo@a%.com"),
  ok.
〗斷ホ乔殘χμё〖 2024-08-10 21:37:04

Ruby225 个字符
这是我的第一个 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

Ruby, 225 chars.
This is my first Ruby program, so it's probably not very Ruby-like :-)

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
蹲墙角沉默 2024-08-10 21:37:04

“不使用正则表达式”:
PHP 47 个字符。

<?=filter_var($argv[1],FILTER_VALIDATE_EMAIL);

'Using no regex':
PHP 47 Chars.

<?=filter_var($argv[1],FILTER_VALIDATE_EMAIL);
何止钟意 2024-08-10 21:37:04

Haskell (GHC 6.8.2),165 161 144C 字符


使用模式匹配,elem, spanall

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 "[email protected]",
  e "[email protected]",
  e "[email protected]",
  not $ e "b@[email protected]",
  not $ e "test@%.org",
  not $ e "[email protected]",
  not $ e "@w.org",
  not $ e "test@org",
  not $ e "s%[email protected]",
  not $ e "foo@a%.com"
  ]

Haskell (GHC 6.8.2), 165 161 144C Characters


Using pattern matching, elem, span and 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

The above was tested with the following code:

main :: IO ()
main = print $ and [
  e "[email protected]",
  e "[email protected]",
  e "[email protected]",
  not $ e "b@[email protected]",
  not $ e "test@%.org",
  not $ e "[email protected]",
  not $ e "@w.org",
  not $ e "test@org",
  not $ e "s%[email protected]",
  not $ e "foo@a%.com"
  ]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文