如果可能的话,我希望对此电子邮件解析器提供一些帮助。
这段代码具有所有适当的声明和初始化,但我不确定我在哪里弄乱这个循环:
while ( getline( fin, lines ) )
{
for ( int i = 0; i < lines.length( ); i++ )
{
if ( lines[ i ] == '@' )
{
for ( s = i; s < lines.length( ); s-- )
{
if ( s < 0 )
{
break;
}
if ( validChar( lines[ s ] ) == false )
{
break;
}
} //for
for ( e = i; e > lines.length( ); e++ )
{
if ( e == lines.length( ) )
{
break;
}
if ( validChar( lines[ e ] ) == false )
{
break;
}
if ( lines[ e ] == '.' )
{
hasDot = true;
}
} // for
anEmail = lines.substr( s, e );
cout << anEmail << endl;
}
} // if
} // while
这是为了这个功能:
bool validChar( char a )
{
bool result = false;
if ( a >= 'A' && a <= 'Z' || a >= 'a' && a <= 'z' || a >= '0' && a <= '9' || a == '.' || a == '-' || a == '+' )
{
result = true;
}
return result;
}
编辑:一个测试用例是文本文件中的这个字符串“这是一个带有DummyTest@my.test的电子邮件文件和其他一些测试文本”,我想要这个“DummyTest@my.test”,我想我只得到这个“@ my.test和其他一些测试文本”
我哪里错了?
答案 0 :(得分:1)
您的问题在这里:
for ( s = i; s < lines.length( ); s-- )
{
//...
if ( validChar( lines[ s ] ) == false )
{
break;
}
} //for
您正在检查lines[s]
是否有效以决定是否终止;但最初是lines[s] == '@'
,因为你刚刚找到了@
!如果您将s
初始化为i - 1
,那么您就会更加接近......但是,您会发现您的substr
有一堆off off off它。您最终需要执行anEmail = lines.substr( s + 1, e + 1 );
但这只会导致代码超过您的测试用例。这不是解析电子邮件地址的有效方法。此方法不适用于所有有效的电子邮件地址,包括"an@sign"@foo
和"spaces are legal only in quotes"@foo
。您还需要扩展validChar来处理实际的有效字符集,这些字符因名称和域而异; !#$%&'*+-/=?^_{}|~@[IPv6:2001:db8:1ff::a0b:dbd0]
完全合法。最后,如果您真正排除非法地址非常重要,那么您将再次受到此方法的限制:double..dot@foo
不合法,double@at@foo
也不合法。
这个来源是RFC822(或它更新的兄弟姐妹RFC5322和RFC6531),你会发现正则表达式无法解析电子邮件,因为name(comment(comment))@foo
是合法的,虽然name(comment))@foo
不是。