Почему делает мой нежадный Perl regex, все еще соответствуют слишком много?

Используйте интерфейс, если Вы предполагаете для поддержки различных классов Повреждения и его иерархии сразу.

Car( new Brake() )
Car( new BrakeABC() )
Car( new CoolBrake() )

И Вы не знаете эту информацию во время компиляции.

, Если Вы знаете, какое Повреждение Вы собираетесь использовать 2b, правильный выбор для Вас определить различные Автомобильные классы. Тормоз в этом случае будет Вашим автомобилем "Стратегия", и можно установить по умолчанию.

я не использовал бы 2a. Вместо этого можно добавить статические методы Повредить и назвать их без экземпляра.

9
задан brian d foy 25 October 2009 в 16:49
поделиться

4 ответа

The problem is that, even though it's not greedy, it still keeps trying. The regex doesn't see

"$tom" said blah blah blash.

and think "Oh, the stuff following the "said" isn't quoted, so I'll skip that one." It thinks "well, the stuff after "said" isn't quoted, so it must still be part of our quote." So ".+?" matches

"$tom" said blah blah blash.  "$dick"

What you want is "[^"]+". This will match two quote marks enclosing anything that's not a quote mark. So the final solution:

("[^"]+" said "[^"]+")
18
ответ дан 4 December 2019 в 08:15
поделиться

Unfortunately " is a peculiar-enough character to need to be treated carefully. Use:

my ($term) = /("[^"]+?" said "[^"]+?")/g;

and it should work fine (it does for me...!). I.e. explicitly match sequences of "nondoublequotes" rather than sequences of arbitrary characters.

3
ответ дан 4 December 2019 в 08:15
поделиться

Others have mentioned how to fix this.

I'll answer how you can debug this: you can see what's happening by using more captures:

 bash$ cat story | perl -nle 'my ($term1, $term2, $term3) = /(".+?") (said) (".+?")/g ; 
      print "term1 = \"$term1\" term2 = \"$term2\" term3 = \"$term3\" \n"; '
 term1 = ""$tom" said blah blah blash.  "$dick"" term2 = "said" term3 = ""blah blah blah""
3
ответ дан 4 December 2019 в 08:15
поделиться

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

Чтобы решить эту проблему, вам нужно сделать ваше регулярное выражение более конкретным (например, сообщить механизму, что $ term не должен содержать никаких кавычек. В любом случае рекомендуется сделать ваши регулярные выражения как можно более конкретными.

Дополнительные сведения и Попав в ловушку относительно регулярных выражений, я рекомендую отличную книгу Джеффри Фридла: Mastering Regular Expressions

2
ответ дан 4 December 2019 в 08:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: