Вам нужно сделать каждый раздел регулярного выражения необязательным, чтобы вы могли опустить этот блок.
Вам нужно взять [h]
из одной из альтернатив - вы соответствуете 12h
, но не 01h
.
У вас не должно быть \d
в конце.
Вы не можете использовать однозначные минуты или секунды. Там также нет необходимости в 60 или 60 м, так как это 1 м и 1 ч.
/^((0?[1-9]|1[0-2])h)?([1-5]?[0-9]m)?([1-5]?[0-9]s)?$/
Нет необходимости заключать h
, m
и s
в квадратные скобки, так как они представляют собой одиночные символы. ]
Обратите внимание, что поскольку каждая единица является необязательной, она также будет соответствовать пустой строке. Вы должны проверить это отдельно от регулярного выражения.
Упущение, что итераторы довольно часто делаются недействительным при изменении контейнера путем вставки или стирания контейнерных участников.
Для многих больших подсказок относительно использования STL я настоятельно рекомендую книгу Scott Meyers "Эффективный STL" (санировал ссылку Amazon),
Проверка принадлежности к диапазону конца должна использовать! = и не <так как порядок указателей не гарантируется.
Пример:
for(it = list.begin(); it != list.end(); ++it)
{
// do stuff
}
Постпостепенное увеличение, когда предварительное постепенное увеличение сделает.
Немногие другие:
Преобразование обратного итератора к основному итератору, не помня, что итератор теперь будет одним элементом вне того, на который это указывало.
Попытка использовать алгоритмы, которые требуют итератора произвольного доступа с итераторами вещей как наборы и карты.
Редактирование ключа записи карты с итератором неконстанты (это, оказывается, основывается на VS.Net, но не будет с GCC),
Используя их, не читая "Эффективный STL" заказывают Scott Meyers.:) Действительно. Это заставляет большинство глупых ошибок уйти.
Надлежащее продолжение после erase()
.
Принятие:
Container::iterator i = cont.begin(), iEnd = cont.end();
Например, на std::map
, это не хорошая идея:
for (; i != iEnd; ++i) {
if (i->second.eraseCondition()) {
cont.erase(i);
}
}
Это работало бы:
for (; i != iEnd; ) {
Container::iterator temp = i;
++temp;
if (i->second.eraseCondition()) {
cont.erase(i);
}
i = temp;
}
И это также:
for (; i != iEnd; ) {
if (i->second.eraseCondition()) {
cont.erase(i++);
}
else {
++i;
}
}
Это было слишком много раз действительно, что я должен был применить эти меры в некотором производственном коде :(
Используя auto_ptr в контейнере, например.
list<auto_ptr<int> > foo;
К счастью, много auto_ptr реализаций в эти дни записано для создания этого невозможным.
Это не только проблема с контейнерами STL - modyfing контейнер, когда итерация по нему почти всегда приводит к проблемам.
Это - очень общий источник ошибок в играх - большинство игровых циклов состоит из итерации по каждому игровому объекту выполнение чего-то. f это что-то добавляет или стирается, элементы от игры возражает контейнеру существует, почти конечно, ошибка.
Решение - имеет два контейнера - objectsToDelete, и objectsToAdd - в игровом коде добавляют объекты к этому контейнеры и обновляют игровой контейнер объектов только после итерации по нему.
objetsToAdd может быть Установлен гарантировать нас, привычка удаляет что-либо больше чем в один раз.
objectsToDelete может быть Очередью, если можно создать Объект, не добавляя, что это к игре возражает контейнеру, или это может быть некоторый другой класс (ObjectCreateCommand?), если Ваш код предполагает, что Экземпляр объекта всегда добавляется к игре, возражает контейнеру непосредственно после создания (например, в конструкторе).
list<int> l1, l2;
// ...
for_each(l1.begin(), l2.end(), do_it());