Как использовать регулярное выражение для сопоставления строки даты и времени, которая содержит символы пробела, нуля и новой строки? - PullRequest
2 голосов
/ 15 апреля 2019

Я перебираю файл, используя fgets, и пытаюсь проверить, соответствует ли строка определенным критериям.

По сути, мой цикл

#define BUFSIZE = 4096;

FILE *txt_file = fopen("some_file.txt", "r");
char buffer[BUFSIZE] = {'\0'};
int i;
while (fgets(buffer, BUFSIZE, txt_file)){
    //some logic

    // Reset buffer string
    for (i=0; i<BUFSIZE; i++)
        buffer[i] = '\0';
}

У меня есть различные строки даты и времени, которые могут принимать форму:

  • yyyy-dd-mm hh:mm:ss
  • yyyy-d-mm hh:mm:ss
  • yyyy-dd-m hh:mm:ss `
  • yyyy-d-m hh:mm:ss

Однако строкам datetime могут предшествовать или не предшествовать пробелы, и они будут иметь нулевые символы (я имею в виду \0 char) из-за того, как я использую buffer.

Я использую следующее регулярное выражение для соответствия одной из вышеперечисленных форм:

.*\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01]).*

(Часть чч: мм: сс не имеет значения.) Если я переведу ее в формат, который C может интерпретировать,

char *regex_str = ".*\\d{4}\\-(0?[1-9]|1[012])\\-(0?[1-9]|[12][0-9]|3[01]).*"

Проблема в том, что я продолжаю получать No Match, когда пытаюсь найти совпадение. В основном в моем цикле while я пытаюсь:

int reti = regcomp(&regex, regex_str, REG_EXTENDED);
if (reti)
    fprintf(stderr, "could not compile regex\n");

reti = regexec(&regex, buffer, 0, NULL, 0);
if (!reti){
    char msgbuf[100];
    regerror(reti, &regex, msgbuf, sizeof(msgbuf));
    fprintf(stderr, "Regex match failed: %s\n", msgbuf);
}

Регулярное выражение компилируется для меня, но просто ничего не находит. Я знаю, что есть нулевые символы и символ новой строки. Я попытался добавить x00+, чтобы проверить наличие нулевых символов, и (\r\n|\r|\n), чтобы проверить новую строку, но я не добился успеха. Что я делаю не так с моим регулярным выражением? Я использовал https://www.regextester.com/, и мое регулярное выражение работает там, но не в C.

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

строка даты и времени, которая содержит пробел, нуль…

Строка AC по определению не может содержать нулевые символы, за исключением завершающего '\0'.

этопросто ничего не найти

Кажется, вы неверно истолковали возвращаемое значение regexec() - вы печатаете сообщение об ошибке if (!reti), но regexec() возвращает ноль для успешного совпадения .

0 голосов
/ 15 апреля 2019

Попробуйте поменять месяц и день

".*\\d{4}-(0?[1-9]|[12][0-9]|3[01])-(0?[1-9]|1[012]).*"

===============

 .* 
 \d{4} 
 -
 (                             # (1 start), Day
      0? [1-9] 
   |  
      [12] [0-9] 
   |  
      3 [01] 
 )                             # (1 end)
 -
 (                             # (2 start), Month
      0? [1-9] 
   |  
      1 [012] 
 )                             # (2 end)
 .* 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...