增强校验E-mail地址有效性

本文介绍了一个用于检查电子邮件地址、IP/DNS主机名及其上级管理域有效性的模块。该模块通过正则表达式验证格式,并进一步检查IP是否属于私有网络、多播地址等。此外,还提供了一个验证顶级域名有效性的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**************************************
' 模块名: 增强校验E-mail地址有效性
' 功能描述:这个模块主要功能是检查e-mail地址、IP/DNS 主机名以及上一级的管理域的有效性,他将给予任何地方最正'确的确认。校验 域/主机名可以查找整个 IPv4地址段并给予标识,私有网络排除,lookback等,若保留范围是被排除的,则进行多点传送。
'返回值:每个函数返回对应的True,校验邮件地址返回Flase则是无效的
’******************************************
Option Explicit


Public Function IsValidEmail(Expression As String) As Boolean
    Dim objRegExp As RegExp
    Set objRegExp = New RegExp
    Expression = Trim(Expression) 'Whack any whitespace at both ends
    objRegExp.IgnoreCase = True
    objRegExp.Pattern = "^[/w/.-]+@((([a-z]([a-z0-9-]{0,61}[a-z0-9])?)/.)+[a-z]{2,}|(/d{1,3}/.){3}/d{1,3})$"
    IsValidEmail = objRegExp.Test(Expression)
    If Not IsValidEmail Then Exit Function 'Failed basic format test, so exit
    
    'separate the domain for the remainder of the tests
    IsValidEmail = IsValidIPHost(Mid$(Expression, InStr(Expression, "@") + 1),False)
End Function


Public Function IsValidIPHost(HostString As String, Optional bReservedAllowed As Boolean = True, Optional bMulticastAllowed As Boolean = False) As Boolean
    Dim sSplit() As String
    Dim objRegEx As RegExp
    Dim intOctet2 As Integer
    
    HostString = Trim(HostString) 'dump any leading/trailing whitespace


    If Len(HostString) < 256 Then
        Set objRegEx = New RegExp
        objRegEx.IgnoreCase = True
        objRegEx.Pattern = "^(([a-z]([a-z0-9-]{0,61}[a-z0-9])?)/.)+[a-z]{2,}$" '|(/d{1,3}/.){3}/d{1,3})$"


        If objRegEx.Test(HostString) Then
            IsValidIPHost = IsTopLevelDomain(Mid$(HostString, InStrRev(HostString, ".") + 1))
        Else
            objRegEx.Pattern = "^(/d{1,3}/.){3}/d{1,3}$"


            If objRegEx.Test(HostString) Then 'we have a dotted-quad
                sSplit = Split(HostString, ".")
                IsValidIPHost = ((sSplit(0) > 255) + (sSplit(1) > 255) + (sSplit(2) > 255) + (sSplit(3) > 255) = 0)
                If Not IsValidIPHost or bReservedAllowed Then Exit Function
                intOctet2 = CInt(sSplit(1))


                Select Case CInt(sSplit(0))
                    Case 10, 127, Is > 239 ' Private Network, Loopback or Reserved
                    IsValidIPHost = False
                    Case 172'Private Network
                    If intOctet2 > 15 And intOctet2 < 32 Then IsValidIPHost = False
                    Case 192'Local Network
                    If intOctet2 = 168 Then IsValidIPHost = False
                    Case 169'Autoconfiguration addresses
                    If intOctet2 = 254 Then IsValidIPHost = False
                    Case Is > 223 'Multicast addresses
                    IsValidIPHost = bMulticastAllowed
                End Select
        Else
            IsValidIPHost = False
        End If
    End If
Else
    IsValidIPHost = False
End If
End Function


Private Function IsTopLevelDomain(DomainString As String) As Boolean
    Dim sTLD As String
    Dim objRegEx As RegExp
    
    sTLD = "AC AD AE AERO AF AG AI AL AM AN AO AQ AR ARPA AS AT AU AW AX AZ" & _
    " BA BB BD BE BF BG BH BI BIZ BJ BM BN BO BR BS BT BV BW BY BZ CA" & _
    " CAT CC CD CF CG CH CI CK CL CM CN CO COM COOP CR CU CV CX CY CZ" & _
    " DE DJ DK DM Do DZ EC EDU EE EG ER ES ET EU FI FJ FK FM FO FR GA" & _
    " GB GD GE GF GG GH GI GL GM GN GOV GP GQ GR GS GT GU GW GY HK HM" & _
    " HN HR HT HU ID IE IL IM In INFO INT IO IQ IR IS IT JE JM JO JOBS" & _
    " JP KE KG KH KI KM KN KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY" & _
    " MA MC MD MG MH MIL MK ML MM MN MO MOBI MP MQ MR MS MT MU MUSEUM" & _
    " MV MW MX MY MZ NA NAME NC NE NET NF NG NI NL NO NP NR NU NZ OM orG" & _
    " PA PE PF PG PH PK PL PM PN PR PRO PS PT PW PY QA RE RO RU RW SA SB" & _
    " SC SD SE SG SH SI SJ SK SL SM SN SO SR ST SU SV SY SZ TC TD TF TG" & _
    " TH TJ TK TL TM TN To TP TR TRAVEL TT TV TW TZ UA UG UK UM US UY UZ" & _
    " VA VC VE VG VI VN VU WF WS YE YT YU ZA ZM ZW"
    
    Set objRegEx = New RegExp
    objRegEx.IgnoreCase = True
    objRegEx.Pattern = "/b" & DomainString & "/b"
    IsTopLevelDomain = objRegEx.Test(sTLD)
End Function 
 
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_STUDENTS 200 #define FILENAME "students.dat" typedef struct { char id[12]; // 学号 char name[20]; // 姓名 int age; // 年龄 char gender[4]; // 性别 char birthday[11]; // 出生年月 (YYYY-MM-DD) char address[100]; // 地址 char phone[15]; // 电话 char email[50]; // E-mail } Student; Student students[MAX_STUDENTS]; int studentCount = 0; // 当前学生数量 // 从文件加载数据 void loadData() { FILE* fp = fopen(FILENAME, "rb"); if (fp) { studentCount = fread(students, sizeof(Student), MAX_STUDENTS, fp); fclose(fp); printf("成功加载 %d 条学生记录\n", studentCount); } else { printf("未找到数据文件,将创建新文件\n"); } } // 保存数据到文件 void saveData() { FILE* fp = fopen(FILENAME, "wb"); if (fp) { fwrite(students, sizeof(Student), studentCount, fp); fclose(fp); printf("数据已保存成功\n"); } else { printf("文件保存失败\n"); } } // 显示菜单 void displayMenu() { printf("\n======== 学生信息管理系统 ========\n"); printf("1. 添加学生信息\n"); printf("2. 浏览所有学生信息\n"); printf("3. 查询学生信息\n"); printf("4. 修改学生信息\n"); printf("5. 删除学生信息\n"); printf("6. 学生信息排序\n"); printf("7. 退出系统\n"); printf("==================================\n"); printf("请选择操作(1-7): "); } // 检查学号是否重复 int isDuplicateId(char* id) { for (int i = 0; i < studentCount; i++) { if (strcmp(students[i].id, id) == 0) { return 1; } } return 0; } // 添加学生信息 void addStudent() { if (studentCount >= MAX_STUDENTS) { printf("系统容量已满!\n"); return; } Student s; printf("\n--- 添加新学生 ---\n"); // 输入并验证学号 while (1) { printf("学号: "); scanf("%s", s.id); if (!isDuplicateId(s.id)) break; printf("学号已存在,请重新输入!\n"); } printf("姓名: "); scanf("%s", s.name); // 验证年龄 while (1) { printf("年龄: "); scanf("%d", &s.age); if (s.age > 0 && s.age < 150) break; printf("年龄无效,请输入0-150之间的数字\n"); } // 验证性别 while (1) { printf("性别(男/女): "); scanf("%s", s.gender); if (strcmp(s.gender, "男") == 0 || strcmp(s.gender, "女") == 0) break; printf("性别输入错误,请重新输入(男/女)\n"); } printf("出生年月(YYYY-MM-DD): "); scanf("%s", s.birthday); printf("地址: "); getchar(); // 清除缓冲区 fgets(s.address, sizeof(s.address), stdin); s.address[strcspn(s.address, "\n")] = 0; // 移除换行符 printf("电话: "); scanf("%s", s.phone); printf("E-mail: "); scanf("%s", s.email); students[studentCount++] = s; saveData(); printf("学生信息添加成功!\n"); } // 显示单个学生信息 void displayStudent(Student s) { printf("| %-12s | %-20s | %-4d | %-4s | %-12s | %-15s | %-30s | %-20s |\n", s.id, s.name, s.age, s.gender, s.birthday, s.phone, s.email, s.address); } // 浏览所有学生信息 void displayAllStudents() { if (studentCount == 0) { printf("没有学生信息可显示\n"); return; } printf("\n%-12s %-20s %-4s %-4s %-12s %-15s %-30s %-20s\n", "学号", "姓名", "年龄", "性别", "出生年月", "电话", "E-mail", "地址"); printf("----------------------------------------------------------------------------------------------------\n"); for (int i = 0; i < studentCount; i++) { displayStudent(students[i]); } printf("共 %d 条记录\n", studentCount); } // 按学号查询 void searchById() { char id[12]; printf("请输入学号: "); scanf("%s", id); printf("\n%-12s %-20s %-4s %-4s %-12s %-15s %-30s %-20s\n", "学号", "姓名", "年龄", "性别", "出生年月", "电话", "E-mail", "地址"); printf("----------------------------------------------------------------------------------------------------\n"); int found = 0; for (int i = 0; i < studentCount; i++) { if (strcmp(students[i].id, id) == 0) { displayStudent(students[i]); found = 1; break; } } if (!found) { printf("未找到学号为 %s 的学生\n", id); } } // 按姓名查询 void searchByName() { char name[20]; printf("请输入姓名: "); scanf("%s", name); printf("\n%-12s %-20s %-4s %-4s %-12s %-15s %-30s %-20s\n", "学号", "姓名", "年龄", "性别", "出生年月", "电话", "E-mail", "地址"); printf("----------------------------------------------------------------------------------------------------\n"); int found = 0; for (int i = 0; i < studentCount; i++) { if (strcmp(students[i].name, name) == 0) { displayStudent(students[i]); found = 1; } } if (!found) { printf("未找到姓名为 %s 的学生\n", name); } } // 修改学生信息 void modifyStudent() { char id[12]; printf("请输入要修改的学生学号: "); scanf("%s", id); int index = -1; for (int i = 0; i < studentCount; i++) { if (strcmp(students[i].id, id) == 0) { index = i; break; } } if (index == -1) { printf("未找到该学生\n"); return; } printf("当前学生信息:\n"); displayStudent(students[index]); Student s = students[index]; int choice; do { printf("\n请选择要修改的信息项:\n"); printf("1.姓名 2.年龄 3.性别 4.出生年月 5.地址 6.电话 7.E-mail 0.完成修改\n"); printf("选择: "); scanf("%d", &choice); switch (choice) { case 1: printf("新姓名: "); scanf("%s", s.name); break; case 2: while (1) { printf("新年龄: "); scanf("%d", &s.age); if (s.age > 0 && s.age < 150) break; printf("年龄无效,请输入0-150之间的数字\n"); } break; case 3: while (1) { printf("新性别(男/女): "); scanf("%s", s.gender); if (strcmp(s.gender, "男") == 0 || strcmp(s.gender, "女") == 0) break; printf("性别输入错误,请重新输入(男/女)\n"); } break; case 4: printf("新出生年月(YYYY-MM-DD): "); scanf("%s", s.birthday); break; case 5: printf("新地址: "); getchar(); fgets(s.address, sizeof(s.address), stdin); s.address[strcspn(s.address, "\n")] = 0; break; case 6: printf("新电话: "); scanf("%s", s.phone); break; case 7: printf("新E-mail: "); scanf("%s", s.email); break; case 0: printf("修改完成\n"); break; default: printf("无效选择\n"); } } while (choice != 0); students[index] = s; saveData(); printf("学生信息已更新\n"); } // 删除学生信息 void deleteStudent() { char id[12]; printf("请输入要删除的学生学号: "); scanf("%s", id); int index = -1; for (int i = 0; i < studentCount; i++) { if (strcmp(students[i].id, id) == 0) { index = i; break; } } if (index == -1) { printf("未找到该学生\n"); return; } printf("将要删除的学生信息:\n"); displayStudent(students[index]); char confirm; printf("确定删除吗?(y/n): "); scanf(" %c", &confirm); if (confirm == 'y' || confirm == 'Y') { for (int i = index; i < studentCount - 1; i++) { students[i] = students[i + 1]; } studentCount--; saveData(); printf("学生信息已删除\n"); } else { printf("删除操作已取消\n"); } } // 比较函数:按出生日期 int compareByBirthday(const void* a, const void* b) { Student* s1 = (Student*)a; Student* s2 = (Student*)b; return strcmp(s1->birthday, s2->birthday); } // 比较函数:按年龄 int compareByAge(const void* a, const void* b) { Student* s1 = (Student*)a; Student* s2 = (Student*)b; return (s1->age - s2->age); } // 学生信息排序 void sortStudents() { if (studentCount == 0) { printf("没有学生信息可排序\n"); return; } int choice; printf("\n请选择排序方式:\n"); printf("1. 按出生日期排序\n"); printf("2. 按年龄排序\n"); printf("选择: "); scanf("%d", &choice); switch (choice) { case 1: qsort(students, studentCount, sizeof(Student), compareByBirthday); printf("已按出生日期排序\n"); break; case 2: qsort(students, studentCount, sizeof(Student), compareByAge); printf("已按年龄排序\n"); break; default: printf("无效选择\n"); return; } displayAllStudents(); } int main() { loadData(); int choice; do { displayMenu(); scanf("%d", &choice); switch (choice) { case 1: addStudent(); break; case 2: displayAllStudents(); break; case 3: printf("\n1. 按学号查询\n2. 按姓名查询\n选择: "); scanf("%d", &choice); if (choice == 1) searchById(); else if (choice == 2) searchByName(); else printf("无效选择\n"); break; case 4: modifyStudent(); break; case 5: deleteStudent(); break; case 6: sortStudents(); break; case 7: saveData(); printf("感谢使用学生信息管理系统!\n"); break; default: printf("无效选择,请重新输入(1-7)\n"); } } while (choice != 7); return 0; }此代码储存结果格式错误
最新发布
06-08
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值