Шаблон Sed Regex соответствует жадному алгоритму, хотя не должен

419
Oliver Friedrich

Я наткнулся на поведение, которое я не могу объяснить, надеюсь, некоторые из вас, ребята, могут мне помочь.

Я пытаюсь сгенерировать некую документацию из более крупного Antпроекта, поэтому я использую ее sedдля фильтрации информации из файлов, которая понадобится мне в документации позже.

У меня есть обычный сборочный файл ant с такими строками:

 <target name="targetA" depends="targetD" description="some fancy description"> ... <target name="targetB" depends="targetD" description="some fancy description"> ... <target name="targetC" depends="targetD" description="some fancy description"> 

Теперь я бегу по этой строке:

sed -nr 's/.*?target name="(.*?)".*="(.*?)".*/ * \1 - \2/p' 

Это должно дать мне:

 * targetA - some fancy description * targetB - some fancy description * targetC - some fancy description 

Вместо этого я получаю:

 * targetA" depends="targetD" - some fancy description * targetA" depends="targetD" - some fancy description * targetA" depends="targetD" - some fancy description 

Я попытался пропустить вывод второй группы, чтобы убедиться, что это первая группа, которая фактически соответствует целой части «зависит» с ней, хотя я установил регулярное выражение как не жадное до следующей двойной кавычки.

Что мне здесь не хватает?

Использование более явного регулярного выражения, как это работает как ожидалось, но я все еще не понимаю, жадность:

sed -nr 's/.*?target name="(.*?)".*=.*="(.*?)".*/ * \1 - \2/p' 

Как это может быть интересно, я использую sed-4.2.2-4ubuntu1 на Ubuntu Linux (установка по умолчанию)

0
Sed регулярные выражения немного ограничены, более ограничены, чем greps. если вы знаете регулярное выражение, вы можете сделать perl one liner http://superuser.com/questions/416419/perl-for-matching-with-regular-expressions-in-terminal http://stackoverflow.com/questions/4794145/ жемчужно-один-лайнер, как-Grep barlop 9 лет назад 0

1 ответ на вопрос

1
Cyrus

Sed не поддерживает не жадные совпадения, как показано в «. *?» выражение.

Попробуй это:

sed -nr 's/.*target name="([^"]*)" .*="(.*)".*/ * \1 - \2/p' file 

Выход:

 * targetA - немного необычного описания * targetB - немного необычного описания * targetC - немного необычного описания 
Кажется, немного за невидимым углом, но действительно работает. Спасибо! Oliver Friedrich 9 лет назад 0