我想要一个正则表达式(尽可能高效,因为我使用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”
答案 0 :(得分:1)
使用negative look-ahead expression:
如果您希望匹配其他内容不匹配的内容,那么否定前瞻是必不可少的:
q(?!u)
表示q
后面没有u
在您的情况下,q
为%
,u
为([.]?[0-9]+)?[a-zA-Z]
(可选点的可选前缀后跟一个或多个数字,后缀为字母)
注意:此表达式在前瞻部分中使用+
,这是一项没有通用支持的功能。如果您的正则表达式引擎不接受它,请将[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;
}