Как насчет этого?
answer = int(input("What should the answer be? "))
guesses = int(input("How many guesses? "))
guess_count = 1
guess_correct = False
while guess_correct is False:
if guess_count < guesses:
guess = int(input("Guess a number: "))
if answer < guess:
print("The number is lower than that.")
elif answer > guess:
print("The number is higher than that")
else: # answer == guess
print("You win!")
break
guess_count += 1
elif guess_count == guesses:
guess = int(input("Guess a number: "))
if guess != answer:
print("You lose; the number was " + str(answer) + ".")
if guess == answer:
print("You win!")
break
Это очень похоже на вашу программу, но там есть пара break
операторов. Это говорит Python немедленно прекратить выполнение этого цикла и перейти к следующему блоку кода (в данном случае ничего). Таким образом, вам не нужно ждать, пока программа оценит условия, указанные вами для цикла while
, прежде чем начинать следующий цикл. Если это помогло решить вашу проблему, было бы здорово, если бы вы щелкнули галочку напротив моего сообщения
Я должен передать regex замену как переменную
Вы? Почему бы не передать ссылку кода? Пример:
sub modify
{
my($text, $code) = @_;
$code->($text);
return $text;
}
my $new_text = modify('foo baz', sub { $_[0] =~ s/foo/bar/ });
В целом, когда Вы хотите передать "что-то, что делает что-то" к подпрограмме ("regex замена" в случае Вашего вопроса), ответ должен передать ссылку на часть кода. Perl Высшего порядка является хорошей книгой по теме.
Ну, можно предварительно скомпилировать РЕ с помощью qr//оператор. Но Вы не можете передать оператор (s///).
$pattern = qr/foo/;
print "match!\n" if $text =~ $pattern;
, Но если необходимо передать оператор замены, Вы - до передачи или код или строки:
proc('$text =~ s/foo/bar');
sub proc {
my $code = shift;
...
eval $code;
}
или, код:
proc(sub {my $text = shift; $text =~ s/foo/bar});
sub proc {
my $code = shift;
...
$code->("some text");
}
sub proc {
my($match, $subst) = @_;
my $txt = "foo baz";
$txt =~ s/$match/$subst/;
print "$txt\n";
}
my $matcher = qr/foo/;
my $sub_str = "bar";
proc($matcher, $sub_str);
Это скорее непосредственно отвечает на Ваш вопрос. Можно сделать более - но когда я использовал qr//термин вместо $sub_str как простой литерал, затем расширенным regex заменили.
Я недавно должен был создать синтаксический анализатор (тестовый синтаксический анализатор) для операторов с некоторыми странными (диалект) типы SQL, распознав строки, такие как это, разделив его на три имен типов:
input: datetime year to second,decimal(16,6), integer
Сценарий я раньше демонстрировал используемый, заключил regexes в кавычки.
#!/bin/perl -w
use strict;
while (<>)
{
chomp;
print "Read: <$_>\n";
my($r1) = qr%^input\s*:\s*%i;
if ($_ =~ $r1)
{
print "Found input:\n";
s%$r1%%;
print "Residue: <$_>\n";
my($r3) = qr%(?:year|month|day|hour|minute|second|fraction(?:\([1-5]\))?)%;
my($r2) = qr%
(?:\s*,?\s*)? # Commas and spaces
(
(?:money|numeric|decimal)(?:\(\d+(?:,\d+)?\))? |
int(?:eger)? |
smallint |
datetime\s+$r3\s+to\s+$r3
)
%ix;
while ($_ =~ m/$r2/)
{
print "Got type: <$1>\n";
s/$r2//;
}
print "Residue 2: <$_>\n";
}
else
{
print "No match:\n";
}
print "Next?\n";
}
Мы можем спорить об использовании имен как $r1 и т.д. Но это сделало задание... это не было и не, производственный код.
eval "$txt =~ $pattern";Это становится
eval "\"foo baz\" =~ s/foo/bar/"и замены не работают над литеральными строками.
Это работало бы:
eval "\$txt =~ $pattern"но это не очень приятно. оценка почти никогда не является правильным решением.
решение zigdon может сделать что-либо, и решение Jonathan довольно подходит, если замещающая строка статична. Если бы Вы хотите что-то более структурированное, чем первое и более гибкое, чем второе, я предложил бы гибрид:
sub proc { my $pattern = shift; my $code = shift; my $txt = "foo baz"; $txt =~ s/$pattern/$code->()/e; print "$txt\n"; } my $pattern = qr/foo/; proc($pattern, sub { "bar" }); # ==> bar baz proc($pattern, sub { "\U$&" }); # ==> FOO baz
s///
не regex. Таким образом Вы не можете передать его как regex.
мне не нравится eval
за это, это очень хрупко с большим количеством bordercases.
я думаю, лучше проявлять подход, подобный тому, который берет JavaScript: передайте обоих regex (в Perl, который является qr//
), и ссылка кода для замены. Например, для передачи параметров для получения того же эффекта как [1 110]
s/(\w+)/\u\L$1/g;
можно звонить
replace($string, qr/(\w+)/, sub { "\u\L$1" }, 'g');
Примечание, что 'g' модификатор не является на самом деле флагом для regex (я думаю, присоединяя его к regex, ошибка дизайна в JavaScript), таким образом, я принял решение передать его в 3-м параметре.
, Как только API был решен, реализация может быть сделана затем:
sub replace {
my($string, $find, $replace, $global) = @_;
unless($global) {
$string =~ s($find){ $replace->() }e;
} else {
$string =~ s($find){ $replace->() }ge;
}
return $string;
}
Позволяют нам попробовать его:
print replace('content-TYPE', qr/(\w+)/, sub { "\u\L$1" }, 'g');
Результат:
Тип контента
, Который выглядит хорошим мне.
Возможно, Вы могли бы заново продумать свой подход.
Вы хотите передать в функции regex замена, вероятно, потому что функция будет получать текст, на который будут управлять из некоторого другого источника (читающий из файла, сокета, и т.д.). Но Вы объединяете регулярное выражение с заменой регулярного выражения.
В выражении, s/foo/bar/
, у Вас на самом деле есть регулярное выражение (" / нечто / ") и замена ("панель"), которая должна заменить то, что подобрано выражением. В подходах Вы попробовали к настоящему времени, Вы столкнулись с проблемами, пытающимися использовать eval
, главным образом из-за вероятности специальных символов в выражении, что любой вмешивается в eval
или будьте интерполированы (т.е. проглотил) в процессе оценки.
Таким образом вместо этого, попытайтесь передать свою стандартную программу два аргумента: выражение и замена:
sub apply_regex {
my $regex = shift;
my $subst = shift || ''; # No subst string will mean matches are "deleted"
# some setup and processing happens...
# time to make use of the regex that was passed in:
while (defined($_ = <$some_filehandle>)) {
s/$regex/$subst/g; # You can decide if you want to use /g etc.
}
# rest of processing...
}
Этот подход обладает дополнительным преимуществом: если Ваш regex шаблон не имеет никаких специальных символов в нем, можно просто передать его в непосредственно:
apply_regex('foo', 'bar');
Или, если это делает, можно использовать qr//
оператор заключения в кавычки для создания объекта regex и передачи, что как первый параметр:
apply_regex(qr{(foo|bar)}, 'baz');
apply_regex(qr/[ab]+/, '(one or more of "a" or "b")');
apply_regex(qr|\d+|); # Delete any sequences of digits
Больше всего Вам действительно не нужно eval
или использование code-references/closures для этой задачи. Это только добавит сложность, которая может сделать отладку тяжелее, чем это должно быть.
Randy