Регулярное выражение имени NetBIOS

У меня есть вопрос по этой ссылке http://support.microsoft.com/kb/188997(Имя компьютера может содержать до 15 буквенно-цифровых символов без пробелов. Имя должно быть уникальным в сети и может содержать следующее специальные символы:! @ # $ % ^ & () - _ ' { } . ~

Следующие символы не допускаются: \ * + = |:; "? < >,)

и я развиваю в C++

поэтому я использовал следующий код, но когда я ввожу символ, который не допускается... он совпадает! Зачем?

 regex  rgx("[a-zA-Z0-9]*(!|@|#|$|%|^|&|\(|\)|-|_|'|.|~|\\{|\\})*[a-zA-Z0-9]*");


string name;
    cin>>name;

if (regex_match(name, rgx))
{
    cout << " Matched :) " << endl;
}
else
    cout << "Not Matched :(" << endl;

Ваша помощь будет принята с благодарностью:)

2 ответа

Решение

Ваше регулярное выражение будет соответствовать любой строке, потому что все ваши квантификаторы "нет или больше символов" (*) и поскольку вы не ищете начала и конца строки, вы будете сопоставлять даже пустые строки. Также вы используете unescaped ^ в пределах одной пары скобок ((...|^|...), который никогда не будет совпадать, если только эта позиция не является началом строки (что может произойти из-за *квантификатор как объяснено выше).

Намного проще достичь того, к чему вы пытаетесь:

regex rgx("^[\\w!@#$%^()\\-'{}\\.~]{1,15}$");

Если вы используете C++11, вы можете использовать необработанную строку для лучшей читаемости:

regex rgx(R"(^[\w!@#$%^()\-'{}\.~]{1,15}$)");

Это должно соответствовать всем действительным именам, содержащим как минимум один (и не более) 15 из выбранных символов.

  • \w соответствует любому "словесному" символу, то есть AZ, az, цифрам и символам подчеркивания (и в зависимости от вашей локали и движка регулярных выражений возможно также умляуты и символы с ударением). Из-за этого может быть лучше заменить его на A-Za-z\d_ в приведенном выше выражении:

    regex rgx("^[A-Za-z\\d_!@#$%^()\\-'{}\\.~]{1,15}$");
    

    Или же:

    regex rgx(R"(^[A-Za-z\d_!@#$%^()\-'{}\.~]{1,15}$)");
    
  • {a,b} является квантификатором, соответствующим предыдущему выражению между a и b разами (включительно).

  • ^ а также $ заставит регулярное выражение заполнить всю строку (так как они будут соответствовать началу и концу).

Смотрите здесь: http://www.cplusplus.com/reference/regex/ECMAScript/. Там у вас есть кое-что о специальных символах (с особым значением для регулярных выражений).

Например, ^ имеет особое значение в регулярном выражении, поэтому вы должны избежать его: \^, Другие специальные символы: $ \ . * + ? ( ) [ ] { } |,

Кроме того, я думаю, что ваше регулярное выражение не позволит такие имена, как a-b-c (несколько частей специальных символов или более двух частей буквенно-цифровых символов).

Другие вопросы по тегам