Van egy fájlom, amelyen sok felhasználói alapértelmezés van. Szeretnék változtatni a szöveg egy részén, de küzdeni fogok találni egy párosítót és helyettesítőt. A következő példa segítségével:
############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### # Trackpad: enable tap to click for this user and for the login screen defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
Szeretném cserélni a következőt: # Trackpad: ...
running "Trackpad: ..."
A probléma lebontása érdekében találtam valamit egy regex tesztelő segítségével:
/\n\n#\s(.*)/g
Ha ezt megpróbálom használni a Vim-ben, ez nem működik nekem:
:/\n\n#\s(.*)/running "\1"/g
Gondolom, a problémám két konkrét kérdésre vezethető vissza:
- Hogyan kerülhetem el a
\n
karakterek keresését, ehelyett győződjön meg arról, hogy az#
nem jelenik meg a keresőcsoport végén? - Hogyan tudom hatékonyan használni a rögzítési csoportokat?
Az alábbiakban néhány nagyszerű válasz található. Nehéz választani mindhárom közül, de úgy érzem, hogy a választ a legpontosabb az eredeti specifikációmra. Javaslom, hogy próbálja ki mindhárom választ a tényleges fájllal , hogy lássa, mit érez irántuk.
Válasz
Csak azért, hogy egyértelmű legyek … Úgy gondolom, hogy azt kérte, hogy ez legyen a csere eredménye?
############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### running "Trackpad: enable tap to click for this user and for the login screen" defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
Ebben az esetben a következő parancsot javaslom:
:%s/\n\n#\s\+\(.*\)/^M^Mrunning "\1"/
A minta magyarázata
:s/PATTERN/REPLACEMENT/
a helyettesítő parancs. A százalékos bejelentkezés az :%s
mezőben az egész fájlon működik, nem csak az aktuális soron.
A \n\n
azt mondja, hogy az érdeklődési sornak üres sor után kell lennie. Ha nem törődött az előző üres sorral, akkor a ^
elegendő lenne.
#\s\+
illeszkedik egy kivonathoz karakter, amelyet egy vagy több szóköz követ. \(.*\)
rögzíti a soron következő összes szöveget.
A helyettesítő szöveg magyarázata
^M^M
beszúrja a sorok két végét a mintában szereplő \n\n
helyettesítésére. Ellenkező esetben a szöveg a sor végére kerül az üres sor előtt. Az egyes ^M
beírásához nyomja meg a Ctrl-V Ctrl-M gombot.
Ezután illessze be az running
sztringet, majd a zárójelben rögzítetteket dupla idézőjelek között.
Megjegyzések
új sorok megszerzéséhez?
Válasz
Valami ilyesmit használnék:
:s/^#\s\+\(.\{-}\):/running "\1":/
-
^#
, hogy megfeleljen a lehorgonyzott#
karakternek a sor elején (ez megválaszolja az 1. kérdést) -
\s\+
, hogy az összes szóköz egy vagy többször megegyezzen -
\(
csoport indításához (ez megválaszolja a 2. kérdést) -
.\{-}\
bármely karakter 0 vagy többszörös megfeleltetéséhez egy csoportban nem mohó módon ; ez annyiban különbözik a.*
től, hogy a lehető legkevesebbet és nem a lehető legnagyobb mértékben próbál egyeztetni. Próbáljon meg hozzáadni egy:
karaktert a megjegyzéshez, és megtudhatja, miért ez számít -
\)
az alcsoport befejezéséhez. -
:
megfelel egy szó szerinti:
Ezt követően ezt kicseréljük a szövegre kívánt, és az \1
segítségével hivatkozhat az általunk elfoglalt csoportra.
Valamivel egy regex tesztelő
A reguláris kifejezés szintaxisa kicsit hasonlít a wiki szintaxisához: van egy csomó közülük, mindegyik egy pillantásra egyforma, egyik sem nyilvánvalóan jobb, mint bármely más, de sok különbség van.
Ma az úgynevezett “Perl kompatibilis” reguláris kifejezések de facto alapértelmezettek a legtöbb nyelvben, de a Vim reguláris kifejezések nem kompatibilis a Perl-kompatibilis kifejezésekkel! A Vim regexp szintaxisa legalább a “70” -re visszanyúlik, amikor Perl még csak nem is volt.
Ezt láthatja az alcsoportokkal, ahol az \(
és nem (
(ez kompatibilis a POSIX “alap” szintaxissal, de nem a gyakoribb POSIX “kibővített” vagy Perl szintaxissal).Ezt úgy vezérelheti, hogy hozzáadja a mintához a \v
zászlót (lásd: :help /\v
részletekért), ez “kompatibilisebbé” teszi, de nem teljesen (még mindig használnia kell a .{-}
-t például nem kapzsi mérkőzésekhez)
Tehát ez megmagyarázhatja, hogy miért működik a „regex tesztelő” szinte, de nem egészen.
http://www.vimregex.com/ a Vim regexps jó áttekintése / csalólapja.
Hozzászólások
- Remek válasz, főleg azzal, hogy miért a regex! Ami a keresést és a cserét illeti, ‘ kissé trükkös, mivel a megjegyzésnek lehet vagy nem
:
. A részletekért lásd a teljes fájlt github.com/squarefrog/dotfiles/blob/master/osx/…
Válasz
Megteheti:
- keresheti azokat a sorokat, amelyek nem érnek véget itt:
#
::/[^#]$/
- cserélje ki a
#\s(.*)
elemet a a sor:s/\v^#\s(.*)/running "\1"/
A csoportok használatához a következőket kell tennie:
- kerülje a zárójeleket, hogy a regex szintaxis részévé válnak:
\(.*\)
, vagy - használnak “varázslatot” a kifejezés kezdete
\v
:s/\v...
Kombinálása:
:/[^#]$/s/\v^#\s(.*)/running "\1"/
Megjegyzések
- Ez remekül működik, köszönöm, hogy nemcsak a szükséges szöveget, hanem magyarázatot is közölt a címkék jelentésével írjon.
- Köszönjük, hogy egyértelművé tette, hogy a zárójelben t o megmenekülni annak érdekében, hogy a regex szintaxis részévé válhasson. Mindig problémám volt a regex csoportokkal a munkába állításban.
:%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/
kifejezésre gondolt (hozzáadta a ” varázslat ” zászló). Nagyon nehéz kiválasztani helyes válasz az eredeti kérdésemre, de úgy érzem, hogy ez a válasz áll a legközelebb az eredeti várható válaszomhoz. Ez az egyetlen, amely az egész fájlban működik, anélkül, hogy ki kellene választania egy tartományt.\r
szót. c63256aa19 “>