【问题标题】:Why is regex always true or always false为什么正则表达式总是真或总是假
【发布时间】:2019-03-12 00:21:50
【问题描述】:

我正在尝试使用正则表达式来确定提供的文件是否具有 .csv 扩展名。

#include <stdio.h>
#include <regex.h>

int match(const char *string, const char *pattern) {
    regex_t re;

    if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) {
        return 0;
    }
    int status = regexec(&re, string, 0, NULL, 0);
    regfree(&re);
    if (status != 0) {
        return 0;
    }

    return 1;
}

int main(void) {
    const char *reg = "^[a-zA-Z0-9-_]{1,}(.csv)$";

    if (!match("test.csv", reg)) {
        printf("Not a valid csv file.\n");
    } else {
        printf("Valid csv file.\n");
    }

    return 0;
}

问题在于,使用match(...),任何事情都会评估为真。另一方面,如果我尝试!match(...),则任何结果都为假。那么,我的代码有什么问题?我只希望 .csv 评估为真,其他一切为假。

示例(和期望的结果):

  • test.csv = true ("有效的 csv 文件。")
  • test.abc = false(“不是有效的 csv 文件。”)

【问题讨论】:

  • 如果match 始终为真,那么!match 将始终为假...我认为您的问题是为什么这个正则表达式不能正确匹配.csv。另外,请记住,这并不能证明某些东西是否是“有效的 csv 文件”,只是扩展名为 .csv
  • 您的错误处理在哪里?你的调试器告诉你什么?你甚至知道执行了哪个return 语句吗?
  • 你应该使用"^[a-zA-Z0-9_-]+\\.csv$"
  • 出于兴趣,检查最后的字符是否为".csv"有什么问题?
  • 说实话,我发现验证扩展名的概念是错误的,你应该检查文件内容是否有效,而不是文件名是否有效。

标签: c regex


【解决方案1】:

您使用的正则表达式不适用于正则表达式风格:连字符必须用于括号表达式的开头/结尾。此外,您需要转义点,否则它将匹配任何字符。

使用

const char *reg = "^[a-zA-Z0-9_-]+\\.csv$";

请参阅C demo

【讨论】:

  • 我还建议使用更好的错误处理机制(使用定义来区分CSV filenot a CSV fileregcomp error 的情况)。
  • 是的,这段代码可以进一步改进,我会比较 status 值和 REG_NOMATCH 的可读性。然而,当前的问题不是代码。
  • 谢谢你,维克托!使用您的正则表达式,我的代码最终似乎正在做它应该做的事情。但是,我自己确实使用了一个在线正则表达式检查器,我的正则表达式也得到了预期的结果。只有在我的代码中它不能正常工作......
  • regexec() 如果模式匹配成功则返回“0”,否则返回 REG_NOMATCH。所以我认为检查任何一个结果都可以吗?!
  • @ci7i2en4 很好,只是它增加了使用专用常量的可读性,这只是恕我直言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 2022-11-10
  • 2019-06-24
  • 1970-01-01
相关资源
最近更新 更多