有 3 种类型的字符A-Z
:a-z
和0-9
。
如何编写正则表达式来匹配所有三种类型中具有一个或多个字符的单词?
例如:
匹配:abAcc88, Ua8za8, 88aA
没有匹配:abc, 118, aa7, xxZZ, XYZ111
这boost::regex re("^[A-Za-z0-9]+$");
行不通。
谢谢
至少 IMO,试图用一个正则表达式来完成这一切是一个糟糕的主意。尽管有可能让它工作,但你最终会得到一个难以理解的混乱。意图根本不明显。
IMO,您最好更直接地表达逻辑(尽管在此过程中使用一两个正则表达式不会受到伤害):
boost::regex lower("[a-z]");
boost::regex upper("[A-Z]");
boost::regex digit("[0-9]");
if (find(string, lower) && find(string,upper) && find(string,digit))
// it passes
else
// it fails
任何接触 REs 最少的人只要看一眼就能弄清楚这是在做什么(即使没有接触 REs,也可能不需要真正的聪明才智来弄清楚这a-z
意味着“角色从a
到z
“)。
假设您分别测试每个单词:
boost::regex re("(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])");
不需要锚。
实际上,如果 boost 不支持环视:
boost::regex re(".*[a-z].*([A-Z].*[0-9]|[0-9].*[A-Z])|.*[A-Z].*([a-z].*[0-9]|[0-9].*[a-z])|.*[0-9].*([a-z].*[A-Z]|[A-Z].*[a-z])");
正如@Bill 所指出的,这是每一种组合。
(\w*[a-z]\w*[A-Z]\w*[0-9]\w*)|(\w*[a-z]\w*[0-9]\w*[A-Z]\w*)|(\w*[A-Z]\w*[a-z]\w*[0-9]\w*)|(\w*[A-Z]\w*[0-9]\w*[a-z]\w*)|(\w*[0-9]\w*[A-Z]\w*[a-z]\w*)|(\w*[0-9]\w*[a-z]\w*[A-Z]\w*)
l = lowerU = upperN = number
1.`(\w*[az]\w*[AZ]\w*[0-9]\w*)`匹配单词__l__U___N___ 2.`(\w*[az]\w*[0-9]\w*[AZ]\w*)`匹配单词__l__N___U___ 3.`(\w*[AZ]\w*[az]\w*[0-9]\w*)`匹配单词__U__l___N___ 4. `(\w*[0-9]\w*[AZ]\w*[az]\w*)`匹配单词__U__N___l___ 5.`(\w*[0-9]\w*[AZ]\w*[az]\w*)`匹配单词__N__U___l___ 6.`(\w*[0-9]\w*[az]\w*[AZ]\w*)`匹配单词__N__l___U___
好吧,如果我们要走非正则表达式路线,那为什么不一直走;-)
const char* c = "abAcc88";
char b = 0b000;
for (; *c; c++) b |= 48 <= *c && *c <= 57 ? 0b001 :
(65 <= *c && *c <= 90 ? 0b010 :
(97 <= *c && *c <= 122 ? 0b100 :
0b000 ));
if (b == 0b111)
{
std::cout << "pass" << std::endl;
}
(它不可读,等等;我在开玩笑。)