正则表达式 - 匹配未跟随某种模式的字符

时间:2017-07-11 11:25:29

标签: c++ regex regex-negation

我想要一个正则表达式(尽可能高效,因为我使用C ++并且引擎效率不高)来匹配任何包含%的字符串,而不是紧跟着:

1)一封信[a-zA-Z]

2).NUMBERS [a-zA-Z]

3)NUMBERS [a-zA-Z]

所以我想匹配这些字符串:“dsfdf(%)dsfgs%d s32523”,“%d%d %% t dsg”

而且我不想匹配这样的字符串:“sfsf%d”,“dfsd%.464d,%353T”

1 个答案:

答案 0 :(得分:1)

使用negative look-ahead expression

  

如果您希望匹配其他内容不匹配的内容,那么否定前瞻是必不可少的:q(?!u)表示q后面没有u

在您的情况下,q%u([.]?[0-9]+)?[a-zA-Z](可选点的可选前缀后跟一个或多个数字,后缀为字母)

Demo 1

注意:此表达式在前瞻部分中使用+,这是一项没有通用支持的功能。如果您的正则表达式引擎不接受它,请将[0-9]+替换为[0-9]{1,20},设置20位数的人为限制。

修改

  

编写自己的解析器怎么样?

如果你需要这个相对简单的正则表达式的最终速度,请使用手写的解析器。这是一个简单的例子:

for (string str ; getline(cin, str) ; ) {
    bool found = false;
    size_t pos = 0;
    while (!found && (pos = str.find('%', pos)) != string::npos) {
        if (++pos == str.size()) {
            found = true;
            break;
        }
        if (str[pos] == '.') {
            if (++pos == str.size()) {
                found = true;
                break;
            }
            if (!isdigit(str[pos])) {
                found = true;
                break;
            }
        }
        while (isdigit(str[pos])) {
            if (++pos == str.size()) {
                found = true;
                break;
            }               
        }
        found |= !isalpha(str[pos]);
    }
    cout << '"' << str << '"' << " : " << found << endl;
}

Demo 2