Причина перечисление не может быть вперед объявлено, состоит в том, что, не зная значения, компилятор не может знать устройство хранения данных, требуемое для перечислимой переменной. Компилятору C++ позволяют определить пространство настоящего хранения на основе размера, необходимого для содержания всех определенных значений. Если все, что видимо, является предописанием, единица перевода не может знать, какой размер ресурса хранения будет выбран - это мог быть символ или интервал или что-то еще.
От Раздела 7.2.5 из Стандарта C++ ISO:
базовый тип перечисления является целочисленным типом, который может представить все значения перечислителя, определенные в перечислении. Это определяется реализацией, какой целочисленный тип используется в качестве базового типа для перечисления за исключением того, что базовый тип не должен быть больше, чем
int
, если значение перечислителя не сможет вписатьсяint
илиunsigned int
. Если список перечислителя пуст, базовый тип - то, как будто перечисление имело единственный перечислитель со значением 0. Значениеsizeof()
относилось к перечисляемому типу, объект перечисляемого типа или перечислитель, является значениемsizeof()
, относился к базовому типу.
Начиная с вызывающая сторона к функции должна знать, что размеры параметров правильно устанавливают стек вызовов, количество перечислений в списке перечисления должно быть известно перед прототипом функции.
Обновление: В C++ 0X синтаксис для предисловия, объявляющего перечислимые типы, был предложен и принят. Вы видите предложение в http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf
Лучше использовать другие возможности языка программирования, чем слишком усердно искать шаблон регулярного выражения.
Вы ищете строки, для которых $ s = ~ / bar /, а не $ s = ~ / foo \ s * bar /
] верно.
Остальная часть приведенного ниже скрипта предназначена только для тестирования.
#!/usr/bin/perl
use strict; use warnings;
my %strings = (
'foo is bar' => 1,
'hello bar' => 1,
'foobar' => 0,
'foo bar' => 0,
'barbar' => 1,
'bar foo' => 1,
'foo foo' => 0,
);
my @accept = grep { $strings{$_} } keys %strings;
my @reject = grep { not $strings{$_} } keys %strings;
for my $s ( @accept ) {
if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) {
print "Good: $s\n";
}
else {
print "Bad : $s\n";
}
}
for my $s ( @reject ) {
if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) {
print "Bad : $s\n";
}
else {
print "Good: $s\n";
}
}
Вывод:
E:\srv\unur> j Good: bar foo Good: hello bar Good: foo is bar Good: barbar Good: foo foo Good: foo bar Good: foobar
Учитывая несколько тестовых примеров
my @match = (
"foo is bar",
"hello bar",
);
my @reject = (
"foobar",
"foo bar",
);
, вы, конечно, можете сделать это, передав результаты одного шаблона другому:
my @control = grep !/foo\s*bar/, grep /bar/ => @match, @reject;
Мы также можем сделать это с одним:
my $nofoo = qr/
( [^f] |
f (?! o) |
fo (?! o \s* bar)
)*
/x;
my $pattern = qr/^ $nofoo bar /x;
Но не надо ' Поверьте мне на слово.
for (@match) {
print +(/$pattern/ ? "PASS" : "FAIL"), ": $_\n";
}
for (@reject) {
print +(/$pattern/ ? "FAIL" : "PASS"), ": $_\n";
}
php:
!preg_match(/foo\s*bar/,$string) && preg_match(/bar/,$string)
perl:
$string !~ /foo\s*bar/ && $string =~ /bar/