Jak mogę sprawić, by mój mecz nie był chciwy w vimie?


479

Mam duży plik HTML z dużą ilością znaczników, który wygląda następująco:

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

Próbuję zrobić Vima wyszukiwania i zamiany, aby pozbyć się wszystkich class="", a style=""jednak mam problemy podejmowania mecz ungreedy.

Moja pierwsza próba była taka

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

ale Vim nie lubi ?. Niestety usunięcie ?powoduje, że mecz jest zbyt chciwy.

Jak mogę sprawić, by mój mecz był nieszczery?


Myślę, że odpowiedź Paula jest dobra. Żeby powiedzieć „?” nie oznacza opcjonalnego w vimie (jeśli tego właśnie chcesz osiągnąć za pomocą „?”)
LB40,

14
@LB, w wielu językach,. *? oznacza, że ​​pasuje do dowolnej postaci, ale nie jest chciwy. Właśnie to stara się osiągnąć.
Randy Morris,

Odpowiedzi:


734

Zamiast .*używać .\{-}.

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

Zobacz także :help non-greedy


37
Niezbyt intuicyjne, czy to coś, co robi tylko vim?
Ehtesh Choudhury,

94
Wszystko ma swój własny język wyrażeń regularnych ... to jeden z największych problemów z regex.
Patrick Farrell

35
Wiele z tych narzędzi dojrzewało w tym samym czasie i niezależnie opracowało własny dialekt języka wyrażeń regularnych. Wiele z tych narzędzi również próbowało rozwiązać różne problemy, więc ma sens, że składnia może być - potencjalnie bardzo różna - w tych implementacjach. Musimy zaakceptować, że tak właśnie działa prawdziwy świat, chociaż czasami utrudnia nam to życie jako programistów. Na szczęście wiele narzędzi obecnie zapewnia przynajmniej implementację wyrażenia regularnego zgodną z Perlem. Niestety Vim nie jest jednym z nich.
Randy Morris

15
Jeśli ktoś taki jak ja ustawi domyślnie swoje wyszukiwanie na \v(bardzo magiczna flaga), będziesz chciał użyć .{-}.
jgillman

48
@Shurane @Ziggy Mnemonic: kontroluje liczbę powtórzeń jak {1,3}robi (nawiasy klamrowe). Znak minus -oznacza: powtórz tak mało, jak to możliwe (mało == minus);)
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

58

Nie chciwe wyszukiwanie w vimie odbywa się za pomocą operatora {-}. Lubię to:

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

Spróbuj:

:help non-greedy


17

Jeśli masz wygodniejszą składnię wyrażeń regularnych PCRE, która

  1. popiera non-chciwego operatora ?, o co prosiłeś w OP; i
  2. nie wymaga backhackingu operatorów grupowania i liczności (całkowicie sprzeczny z intuicją wymóg vim, ponieważ nie pasujesz literalnych znaków, ale określasz operatory); i
  3. masz [g] vima skompilowanego z funkcją perla, przetestuj za pomocą

    : sprawdź i sprawdź funkcje; jeśli + perl jest tam, to możesz iść)

spróbuj wyszukać / zamień za pomocą

:perldo s///

Przykład. Zamień atrybuty src i alt w znaczniku 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>

1
perldodziała świetnie, ale niestety nie podświetla wybranego testu podczas pisania wyrażenia regularnego.
mljrg

12

Przekonałem się, że dobrym rozwiązaniem tego typu pytań jest:

:%! sed ...

(lub perl, jeśli wolisz). IOW, zamiast poznawać osobliwości wyrażeń regularnych vima, użyj narzędzia, które już znasz. Używanie perla sprawi, że? modyfikator działa, aby nie dopracować dopasowania.


2
Dobra uwaga, ale /patternsprawdzanie poprawności dopasowania wzorca przed zastosowaniem go i używanie cmodyfikatora w vimie również jest fajne :)
João Portela

to jest poprawne. wszystkie rozwiązania tutaj nie są bliskie chciwości! jeśli musisz dopasować [0-9] \ {7} w linii z dużą ilością tekstu i kilkukrotnym wystąpieniem tego wzorca, żadne rozwiązanie tutaj nie zrobi. Rozwiązania tutaj działają tylko w przypadku prostych rzeczy (o co należy uczciwie zapytano). ale jeśli robisz coś więcej niż szukanie do następnego cytatu, vim nie pomoże.
gcb

4

Z \v(jak zasugerowano w kilku komentarzach)

:%s/\v(style|class)\=".{-}"//g


-4

Dzień dobry

Przetwarzanie wyrażeń regularnych Vima nie jest zbyt genialne. Przekonałem się, że składnia wyrażeń regularnych dla sed jest odpowiednia dla możliwości vima.

Zazwyczaj włączam podświetlanie wyszukiwania (: set hlsearch), a następnie gram regexp po wprowadzeniu ukośnika, aby przejść do trybu wyszukiwania.

Edycja: Mark, ta sztuczka mająca na celu zminimalizowanie zachłannego dopasowania jest również opisana w doskonałej książce Dale Dougherty „Sed & Awk” ( oczyszczony link do Amazon ).

Rozdział trzeci „Zrozumienie składni wyrażeń regularnych” to doskonałe wprowadzenie do bardziej prymitywnych funkcji wyrażeń regularnych związanych z sed i awk. Tylko krótki odczyt i gorąco polecam.

HTH

Twoje zdrowie,


7
Przetwarzanie wyrażeń regularnych Vima jest właściwie całkiem niezłe. Może robić rzeczy, których sed nie może, na przykład dopasowywać numerów wierszy / kolumn lub dopasowywać na podstawie klasyfikacji znaków w języku dla słów kluczowych lub identyfikatorów lub białych znaków. Ma również asercje o zerowej szerokości i możliwość umieszczania wyrażeń po prawej stronie zamiennika. Jeśli \vgo użyjesz , pomoże to wyczyścić składnię.
Brian Carper,

1
@Brian, na zdrowie. Zrobię wyrażenie regularne i zobaczę, czego mi brakowało.
Rob Wells,

@RobWells, Sed & Awk , który jest naprawdę bardzo dobrym imho książkowym, nie wydaje żadnych słów na chciwe / leniwe kwantyfikatory. Jako dowód, w książce absolutnie nie ma słów „ chciwość” ani „ zachłanność ”, a słowo „ leniwe” jest tylko jedno, ale niezwiązane .
Enrico Maria De Angelis

@EnricoMariaDeAngelis jest, ale przykład nie odnosi się wprost do tego terminu. Chodzi o to, jak dostosować wyrażenie regularne do użycia operatora „nie”, aby osiągnąć niepasujące dopasowania. Termin „chciwi i leniwi” pojawił się w silniku NFA Perla, kiedy wprowadzono operatorów, aby specjalnie zmodyfikować zachłanne dopasowanie.
Rob Wells,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.