Как я могу сделать мой матч не жадным в VIM?

481

У меня большой HTML-файл с разметкой, который выглядит следующим образом:

<p class="MsoNormal" style="margin: 0in 0in 0pt;">
  <span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p>

Я пытаюсь сделать Vim поиска и замены , чтобы избавиться от всего class=""и , style=""но у меня возникают проблемы , делая матч ungreedy.

Моя первая попытка была

%s/style=".*?"//g

но Vim, кажется, не нравится ?. К сожалению, удаление ?делает матч слишком жадным.

Как я могу сделать мой матч несвязным?

Марк Бик
источник
Я думаю, что ответ Павла хороший. Просто сказать, что "?" не означает необязательный в vim (если это то, чего вы хотите достичь с помощью «?»)
LB40
15
@LB, на многих языках. *? означает соответствовать любому символу, но быть не жадным. Это то, что он пытается достичь.
Рэнди Моррис

Ответы:

735

Вместо .*использования .\{-}.

%s/style=".\{-}"//g

Также см :help non-greedy

Рэнди Моррис
источник
38
Не очень интуитивно понятно, это делает только vim?
Этеш Чоудхури
95
У всего есть свой собственный язык регулярных выражений ... это одна из самых больших проблем с регулярными выражениями.
Патрик Фаррелл
35
Многие из этих инструментов выросли примерно в одно и то же время и независимо разработали свой собственный диалект языка регулярных выражений. Многие из этих инструментов также пытались решить различные проблемы, поэтому имеет смысл, что синтаксис может сильно отличаться в этих реализациях. Мы должны признать, что именно так работает реальный мир, хотя иногда он усложняет нашу жизнь как разработчиков. К счастью, в наши дни многие инструменты предоставляют Perl-совместимую реализацию регулярных выражений. К сожалению, Вим не один из них.
Рэнди Моррис
15
Если кто-то, как я, по умолчанию их поиск \v(очень магический флаг), вы захотите использовать .{-}.
jgillman
48
@Shurane @Ziggy Mnemonic: контролирует количество повторений, как это {1,3}делает (фигурные скобки). Знак минус -означает: повторить как можно меньше (немного == минус);)
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
58

Нежадный поиск в vim выполняется с помощью оператора {-}. Нравится:

%s/style=".\{-}"//g

просто попробуй:

:help non-greedy
Вильгельм Грей
источник
48

Что случилось с

%s/style="[^"]*"//g
Пол Томблин
источник
7
Хотя, для моей же пользы, я все же хотел бы лучше понять несносную вещь.
Марк Бик
17

Если вам удобнее использовать синтаксис регулярных выражений PCRE, который

  1. поддерживает не жадный оператор?, как вы спросили в OP; а также
  2. не требует подмены группирования и операторов кардинальности (крайне противоречивое требование синтаксиса vim, поскольку вы не сопоставляете буквенные символы, а задаете операторы); а также
  3. у вас [g] vim скомпилирован с возможностью perl, протестируйте используя

    и проверить особенности; если есть + perl, ты идешь)

попробуйте поискать / заменить используя

:perldo s///

Пример. Поменяйте местами атрибуты src и alt в теге img:

<p class="logo"><a href="/"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt=""></a></p>

:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/

<p class="logo"><a href="/"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png"></a></p>
FrDarryl
источник
1
perldoпрекрасно работает, но, к сожалению, не выделяет выбранный тест при наборе регулярного выражения.
mljrg
12

Я обнаружил, что хорошее решение этого типа вопроса:

:%! sed ...

(или perl, если вы предпочитаете). IOW, вместо того, чтобы изучать особенности регулярных выражений vim, используйте инструмент, который вы уже знаете. Использование Perl сделает? модификатор работы, чтобы разогнать матч.

Уильям Перселл
источник
2
хороший момент, но возможность /patternпроверить правильность сопоставления с шаблоном перед его применением и использование cмодификатора в регулярном выражении vim также неплохо :)
João Portela
это правильно. все решения здесь не близки к не жадным! если вам нужно сопоставить [0-9] \ {7} в строке с большим количеством текста и несколькими вхождениями этого паттерна, никакое решение здесь не подойдет. Решения здесь работают только для простых вещей (чтобы быть справедливым, это то, что спросили). но если вы делаете немного больше, чем поиск до следующей цитаты, vim не поможет.
gcb
4

С \v(как предлагается в нескольких комментариях)

:%s/\v(style|class)\=".{-}"//g
JJoao
источник
2

Плагин eregex.vim обрабатывает не жадные операторы в стиле Perl *?и+?

Bain
источник
@xsilenT github.com/othree/eregex.vim : «Рекомендуется установить скрипт, используя Vundle или патоген».
eXe
извините за это я не знаю, как использовать Vundle или патоген.
Xsilen T
-4

G'day,

Обработка регулярных выражений в Vim не слишком блестящая. Я обнаружил, что синтаксис регулярного выражения для sed примерно соответствует возможностям vim.

Я обычно устанавливаю подсветку поиска (: set hlsearch) и затем играю с регулярным выражением после входа в косую черту, чтобы войти в режим поиска.

Редактировать: Отметьте, этот трюк, чтобы минимизировать жадное сопоставление, также описан в превосходной книге Дейла Догерти "Sed & Awk" ( очищенная ссылка Amazon ).

Глава третья «Понимание синтаксиса регулярных выражений» - отличное введение в более примитивные возможности регулярных выражений, связанные с sed и awk. Только краткое чтение и настоятельно рекомендуется.

НТН

веселит,

Роб Уэллс
источник
7
Обработка регулярных выражений в Vim на самом деле довольно приятная. Он может делать то, чего не умеет sed, например совпадать по номерам строк / столбцов или совпадать на основе классификации символов для каждого языка в качестве ключевых слов или идентификаторов или пробелов. Он также имеет утверждения нулевой ширины и возможность помещать выражения в правой части замены. Если вы используете \vего, это поможет очистить синтаксис.
Брайан Карпер
1
@ Брайан, ура. Я сделаю регулярное выражение помощи и посмотрю, чего мне не хватало.
Роб Уэллс
@RobWells, Sed & Awk , действительно хорошая книга imho, явно не тратит слов на жадные / ленивые квантификаторы. В качестве доказательства, в книге не встречается слов « жадность» или « жадность» , и есть только одно, но не связанное с этим, слово « ленивый» .
Энрико Мария Де Анжелис
@ EnricoMariaDeAngelis это так, но пример не относится к термину в явном виде. Речь идет о том, как настроить ваше регулярное выражение для использования оператора «not» для достижения не жадных совпадений. Термин жадный и ленивый появился в движке NFA Perl, когда они представили операторов, которые специально модифицировали жадные совпадения.
Роб Уэллс