Vim Regex Capture Groups [bau -> byau: ceu -> cyeu]
У меня есть список слов:
bau
ceu
diu
fou
gau
Я хочу превратить этот список в:
byau
cyeu
dyiu
fyou
gyau
Я неудачно попробовал команду:
:%s/(\w)(\w\w)/\1y\2/g
Учитывая, что это не работает, что я должен изменить, чтобы заставить группы захвата регулярных выражений работать в Vim?
5 ответов
Один из способов исправить это - убедиться, что шаблон заключен в экранированные скобки:
:%s/\(\w\)\(\w\w\)/\1y\2/g
Немного короче (и больше волшебно -al) использовать \v
Это означает, что в шаблоне после него все символы ASCII, кроме '0'-'9'
, 'a'-'z'
, 'A'-'Z'
а также '_'
имеют особое значение:
:%s/\v(\w)(\w\w)/\1y\2/g
Увидеть:
:help \(
:help \v
Вы также можете использовать этот шаблон, который короче:
:%s/^./&y
%s
применяет шаблон ко всему файлу.^.
соответствует первому символу строки.&y
добавляетy
после картины.
Если вы не хотите избегать групп захвата с помощью обратной косой черты (это то, что вы пропустили), сделайте \v
превратить движок регулярных выражений Vim в очень волшебный режим:
:%s/\v(\w)(\w\w)/\1y\2/g
Вы также должны избежать группового парантеза:
:%s/\(\w\)\(\w\w\)/\1y\2/g
Это делает трюк.
Очень хорошо! При выборе используйте следующее (например):
:'<,'>s/^\(\w\+ - \w\+\).*/\1/
или же
:'<,'>s/\v^(\w+ - \w+).*/\1/
который разбирает
Space - Commercial - Boeing
к
Space - Commercial
.
Объяснение:
-
^
: соответствует началу строки -
\
-побег(
,+
,)
за первое регулярное выражение (принятый ответ) - или добавьте\v
(ответ @ingo-karkat) -
\w\+
находит слово (\w
найдет первый символ): в этом примере я ищу слово, за которым следует другое слово) -
.*
после того, как группа захвата необходима, чтобы найти / сопоставить / исключить оставшийся текст
Дополнение. Это немного не по теме, но я бы предположил, что Vim не очень хорошо подходит для выполнения более сложных выражений / захватов регулярных выражений. [Я делаю что-то подобное следующему, и именно так я нашел эту ветку.]
В таких случаях, вероятно, лучше выгрузить строки в текстовый файл и отредактировать его «на месте» (
sed -i ...
) или в редиректе (
sed ... > out.txt
).
echo 'Space Sciences - Private Industry - Boeing' | sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/'
Space Sciences - Private Industry
touch ~/in.txt
touch ~/out.txt
echo 'Space Sciences - Private Industry - Boeing' > ~/in.txt
cat in.txt
Space Sciences - Private Industry - Boeing
sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/' ~/in.txt > ~/out.txt
cat ~/out.txt
Space Sciences - Private Industry
## Caution: if you forget the > redirect, you'll edit your source.
## source unaltered:
cat in.txt
Space Sciences - Private Industry - Boeing
## edit in place:
sed -i -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/' ~/in.txt
cat in.txt
Space Sciences - Private Industry
Это выражение,
sed -r 's/^((\w+ ){1,2}- (\w+ ){1,2}).*/\1/'
, позволяет гибко находить
{x,y}
повторения слова (слов) - см. https://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html . Здесь, поскольку мои фразы разделены
-
, Я могу просто настроить эти параметры, чтобы получить то, что мне нужно.