2013-05-09 2 views
2

Существует 3 типа символов: A-Z, a-z и 0-9.Регулярное выражение для соответствия одному или нескольким символам каждого типа?

Как написать регулярное выражение для соответствия словам, которые имеют один или несколько символов во всех трех типах?

Например:

Match: abAcc88, Ua8za8, 88aA

Нет матча: abc, 118, aa7, xxZZ, XYZ111

Это boost::regex re("^[A-Za-z0-9]+$"); не работает.

Благодаря

+0

Итак, вы хотите совпадения, чтобы иметь комбинацию из двух больших букв, заглавных букв и цифр? –

+0

У вас может быть только регулярное выражение - '[az] [AZ] [0-9]' и есть все комбинации '[az]', '[AZ]' и '[0-9]' 'или' ред? например '([a-z] [A-Z] [0-9]) | ([0-9] [a-z] [A-Z])' У вас будет куча '|' для всех комбинаций. – Bill

+0

@ Joachim Pileborg, нет трех, но должен иметь одну или несколько маленьких букв, одну или несколько заглавных букв и одну или несколько цифр. – lukasz

ответ

2

Предполагая, что вы проверяете каждое слово отдельно:

boost::regex re("(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])"); 

Нет необходимости анкеров.


На самом деле, в случае повышения не поддерживает lookarounds:

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 указал.

+0

'или' все комбинации будут уродливыми, поэтому я искал какое-то изящное решение .... если возможно :) – Bill

+0

Это работает: boost :: regex re ("(? =. * [az]) (? =. * [AZ]) (? =. * [ 0-9]) \\ S {8} "); Благодаря! – lukasz

3

По крайней мере, ИМО, пытаясь сделать это с помощью одного регулярного выражения, является плохой идеей. Хотя можно заставить его работать, вы получаете нечитаемый беспорядок. Цель не очевидна.

ИМО, вы бы гораздо лучше выразить логику более непосредственно (хотя с помощью регулярных выражений или два в процессе не повредит):

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, чтобы понять, что это делает (и даже без воздействия RE, вероятно, не требуется действительно массивного блеска, чтобы понять, что a-z означает «персонажи из a до z»).

+0

+1 для удобства чтения и обслуживания! – Bill

+0

И, несмотря на потенциальное сканирование строки три раза, это, вероятно, работает лучше, чем одно большое волосатое регулярное выражение, которое пытается адресовать все 6 возможных порядков трех классов символов ... Я не тестировал, хотя ... – twalberg

1

(\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*)

л = нижняяU = верхнийN = число

 
1. `(\w*[a-z]\w*[A-Z]\w*[0-9]\w*)` Match words __l__U___N___ 
2. `(\w*[a-z]\w*[0-9]\w*[A-Z]\w*)` Match words __l__N___U___ 
3. `(\w*[A-Z]\w*[a-z]\w*[0-9]\w*)` Match words __U__l___N___ 
4. `(\w*[0-9]\w*[A-Z]\w*[a-z]\w*)` Match words __U__N___l___ 
5. `(\w*[0-9]\w*[A-Z]\w*[a-z]\w*)` Match words __N__U___l___ 
6. `(\w*[0-9]\w*[a-z]\w*[A-Z]\w*)` Match words __N__l___U___ 
0

Ну, если мы собираемся идти, не регулярное выражение маршрута, то почему бы не взять все пути ;-)

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; 
} 

(Это невозможно прочитать и т. Д .; Я шучу.)

Смежные вопросы