Проверка подлинности электронной почты на C с помощью glibc regex.h

ОК ... получил его для работы с этим регулярным выражением:

const char * reg_exp = "^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*@([a-z0-9])"
                       "(([a-z0-9-])*([a-z0-9]))+(.([a-z0-9])([-a-z0-9_-])?";

Я пока не понимаю, насколько эффективно это выражение, но я счастлив добиться определенного прогресса в этой проблеме.


Совпадение нового с C (регулярное выражение). Я считаю, что я пытался найти ответ на свою проблему.

Я пытаюсь получить простой шаблон электронной почты для работы в моем модуле регистрации. По мере того, как я его теперь кодировал, он не смог сопоставить правильно отформатированный источник электронной почты на каждом проходе. Я думаю, основываясь на моих очень ограниченных знаниях и понимании, что следующий код должен работать, если выполняются все другие зависимости. Но, опять же, это просто не работает. Любая помощь будет высоко ценится.

Обновленный пример кода:

#include 

regex_t regex;
... //other proc vars
int r, e;
unsigned char buf[RESBUF];
char *source = "[email protected]";

const char *reg_exp1 = "/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@"
                       "([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|"
                       "edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])"
                       "|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i";
const char *reg_exp2 = "\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}\b";

char proc[] = "create_user";

r = regcomp(&regex,reg_exp2,REG_EXTENDED);
if(r) {
     sprintf(emessage,"REGEX COMPILE:Fail:%s:%s",proc,cgiRemoteAddr);
     log_proc(ebs->r,emessage,TXLOG);
     e = 1;
}
else {
     e = 0;
}
r = regexec(&regex,source,0,NULL,0);//source email
if(!r) {
     e = 0;
}
else
if(r == 1) {
     sprintf(emessage,"REGEX MATCH:Fail:%s",proc);
     log_proc(ebs->r,emessage,TXLOG);
     e = 1;
}
else {
     regerror(r,&regex,buf,100);
     sprintf(emessage,"REGEX MATCH:Fail:%s:%s",proc,buf);
     log_proc(ebs->r,emessage,TXLOG);
     e = 1;
}
regfree(&regex);
// Now evaluate e to determine success
if (!e) { ... }
0
nl ja de

3 ответы

В источнике C, если вы хотите, чтобы механизм регулярных выражений видел обратную косую черту, вам нужны две обратные косые черты в строковом литерале. Принимая более простые из ваших двух:

const char *reg_exp2 = "\\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\\.[A-Z]{2,4}\\b";

Конечно, если регулярное выражение считывается из файла, ему требуется только одна обратная косая черта в файле; главное, что обратная косая черта находится в строке, отправленной движку регулярных выражений.

подсказки:

  1. When debugging, print the regex input string.
  2. Pay attention to compiler warnings. GCC 4.7.1 says of your second string:

    x.c:1:24: warning: unknown escape sequence: '\.' [enabled by default]
    
0
добавлено
Хммм ... ну минимальное изменение, которое я сделал, не исправило ваш оригинальный reg_exp2 настойчивость в прописных буквах по адресу электронной почты; ваша рабочая ревизия имеет все строчные буквы. И реальные адреса электронной почты фактически не учитывают регистр. Обозначение с регулярным выражением чувствительно к регистру, поэтому вам, вероятно, понадобится [A-Za-z] в ваших классах символов (плюс любые другие допустимые символы). Ваша пересмотренная (но работающая) версия выглядит так, как будто она слишком щедра; это позволит именам, таким как кто-то @ где-то, как действительный адрес электронной почты (а также [email protected]).
добавлено автор Jonathan Leffler, источник
Есть две части для отладки вашего регулярного выражения: одно, убедившись, что движок регулярных выражений видит то, что вы намерены его видеть, чего не произошло, потому что нотация "\ b" встраивала backspace в ваше регулярное выражение ( совершенно легитимный как часть регулярного выражения, а не как часть адреса электронной почты). Вторая часть гарантирует, что регулярное выражение, которое вы используете, соответствует тому, которое соответствует вашему контенту. Вы должны выполнить обе задачи и получить оба права. И хороший тест будет иметь набор действительных и недействительных адресов электронной почты для выполнения.
добавлено автор Jonathan Leffler, источник
@Jonathan ... Я пробовал использовать \\ escape-последовательность, и это тоже не удалось. Однако я получил его для работы с: «^ ([a-z0-9]) (([- a-z0-9 ._]) * ([a-z0-9])) * @ ([a- z0-9]) (([а-z0-9- & ZWNJ;]) * ([а-z0-9])) + (([а & ZWNJ;. -z0-9]) ([- а-г0 -9 _-]) & ZWNJ;?»
добавлено автор Rico, источник

This regex will do it: \b[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b without the domain checking you are using. Read the description of it here: http://www.regular-expressions.info/email.html

Чтобы добавить домен, проверяющий конец, будет выглядеть примерно так, как у вас:

<�Код> \ б [A-Za-z0-9 ._% + -] + @ [A-Za-z0-9 .-] + \. (Са | ком | информация | Edu | ...) \ б

<�Сильный> ИЗМЕНИТЬ

Для простоты попробуйте напрямую передать шаблон функции regcomp. Вычеркните этот код из примера POSIX:

reti = regcomp(&regex, "[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,4}", 0);
    if( reti ){ fprintf(stderr, "Could not compile regex\n"); exit(1); }

/* Execute regular expression */
    reti = regexec(&regex, "[email protected]", 0, NULL, 0);
    if( !reti ){
            puts("Match");
    }
    else if( reti == REG_NOMATCH ){
            puts("No match");
    }
    else{
            regerror(reti, &regex, msgbuf, sizeof(msgbuf));
            fprintf(stderr, "Regex match failed: %s\n", msgbuf);
            exit(1);
    }

Link: http://www.peope.net/old/regex.html

0
добавлено
Вы не видели фактическое регулярное выражение для адреса электронной почты, описанного в RFC ...
добавлено автор nhahtdh, источник
Это хорошо протестированная реализация с этого сайта (единственное, что я сделал, это явно указать строчные символы). Можете ли вы дважды проверить, что ваши входы не обернуты чем-то (например, кавычками?) Или какой-то другой проблемой с тем, как они передаются? Также попробуйте оригинальное регулярное выражение с сайта. Если он не работает, когда он реализован, как описано, проблема связана не с регулярным выражением, а с другим кодом. Также, пожалуйста, напишите обновленный код, как только вы это сделаете.
добавлено автор Matthew, источник
Я хочу, чтобы мой C был менее ржавым, но, глядя на это снова, я думаю, что может возникнуть проблема в том, как вы передаете/устанавливаете свои указатели/переменные. Надеюсь, кто-то еще может закончить эту мысль, кто работал с C совсем недавно, чем 12 лет назад.
добавлено автор Matthew, источник
@nhahtdh Ссылка, которую я опубликовал, имеет это, чтобы сказать об этом: официальный стандарт известен как RFC 2822. Он описывает синтаксис, которому должны соответствовать действительные адреса электронной почты. Вы можете (но вы не должны читать) реализовать его с помощью этого регулярного выражения: ... :) - Я немного обманываю в контексте комментария.
добавлено автор Matthew, источник
Если вы просто выполняете код, который я вставлял, он работает? Что произойдет, если библиотека regcomp отсутствует или возникла проблема, вы получите одно и то же сообщение об ошибке? (Мой вопрос, может быть, ваше Regex вообще не оценивается?)
добавлено автор Matthew, источник
Спасибо, Мэтью за ответ. Все еще не получается матч. Некоторый фон: код, конечно, получает адрес электронной почты через ajax без проблем.
добавлено автор Rico, источник
Как и было предложено, я рассмотрел учебник Ян Гойерертса и обновил код, как показано выше. Однако даже при использовании процедуры, определенной переменной «char * source = [email protected]», вызов regexec (как определено) не соответствует исходному.
добавлено автор Rico, источник
Мэтью ... даже попробовал метод прямых параметров. Результат тот же. Это - ум, ошеломляющий меня. Я более чем знаком с C, и все же я чувствую себя учеником 1-го курса в области компьютерного программирования. Это должно сработать так, что он является таким базовым для интерфейса и содержит ссылки на многие из представленных в Интернете примеров.
добавлено автор Rico, источник
Код, который вы опубликовали, - это то, что я использовал для моделирования моего кода, и это не сработало. Регулярное выражение, конечно, оценивалось с момента его регистрации. Проблема, похоже, была решена, когда я использую флаг расширения в regcomp и не распространяюсь на regexec. Я доказал это, играя с этими двумя конфигурациями флагов. Сейчас он работает, и я ценю вашу помощь.
добавлено автор Rico, источник

Первым шагом было бы сделать обработку ошибок приемлемой. Вместо сообщения об ошибке «Код ошибки REGEX MATCH: Fail:% s» , а не как бесполезное , вам нужны сообщения об ошибках, описывающие проблему ( не начинался с буквы отсутствует значок «@» , несколько символов '@' , нераспознанный домен верхнего уровня и т. д.). Это важно для отладки (например, когда вы что-то пропускаете) и, возможно, даже более важно, если задействован ввод пользователя (и обратная связь для неправильного ввода пользователя).

Как только обработка ошибок будет приемлемой, у вас будет много небольших/тривиальных регулярных выражений, которые намного легче понять и поддерживать и проверять. Это будет больше кода, но это будет хороший код, а не тарабарщина.

Следующий шаг - улучшить код, заменив эти маленькие/тривиальные регулярные выражения на более простые/быстрые проверки, которые вообще не используют регулярные выражения. Когда все регулярные выражения исчезнут, вы знаете, что правильно используете регулярные выражения. :-)

0
добавлено
Я думаю, что проверка конкретных вопросов может быть слишком сложной для вещей с хорошо известным форматом, таким как адрес электронной почты.
добавлено автор Matthew, источник
Я согласен с тобой, Мэтью. Я пытаюсь просто заставить регулярное выражение сначала работать с надлежащим форматом электронной почты, прежде чем начинать входить в более строгие методы.
добавлено автор Rico, источник