C 中的正则表达式限制扩展 ASCII 字符集

Regex in C to restrict Extended ASCII character set

我需要一个 C 中的正则表达式能够匹配除长度大于 0 的扩展 ASCII 的前 32 个字符之外的所有字符。我认为最简单的方法是像 "^[^\x00-\x20]+$" 这样的模式,但事实并非如此按我的预期工作。由于某种原因,它不会匹配 48 到 92 之间的任何字符。知道这个模式有什么问题吗?我该如何解决?

Link to Extended ASCII character set table

从未在 C 中使用正则表达式。接下来我会使用 unsigned char 来适应 EASCII

void match(const unsigned char *src, unsigned char *dst) {
    while (*src) {
        if (*src >= 32) {
            *dst++ = *src++;
        } else {
            src++;
        }
    }
    *dst = 0;
}

Posix 正则表达式库(即 regex.h 中的函数,包括 regcompregexec 解释标准 C 反斜杠序列。它真的不需要,因为 C 会在您编译字符串文字时进行这些扩展。 (如果您接受来自用户输入的正则表达式,则必须考虑这一点。)\ 在正则表达式中的唯一用途是转义特殊字符(在 REG_EXTENDED 模式下),或者使特殊字符(在基本正则表达式模式下,应避免使用。)

所以如果你想排除从\x01\x20的字符,你会写:

 "^[^\x01-\x20]+$"

请注意,您必须将 REG_EXTENDED 标志提供给 regcomp 才能正常工作。

您可能会注意到,这并不排除 NUL (\x00)。无法将 NUL 插入正则表达式模式,因为 NUL 不是 C 字符串中的有效字符;它将终止字符串。出于同样的原因,尝试从 C 字符串中排除 NUL 字符是没有意义的,因为不可能有任何字符。但是,如果它让您感觉更好,您可以使用:

"^[\x21-\xFF]+$"

在语义上,这两个正则表达式模式是相同的(至少,在默认 "C" 语言环境中并假设 char 是 8 位)。

字符 class 如您所写,[^\x00-\x20] 包含除字符 x 以外的所有内容以及从 0 (48) 到 [=15= 的范围] (92). (该范围与字符 02\ 重叠,这些字符被明确命名,其中一些被命名两次。)