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 . Здесь, поскольку мои фразы разделены -, Я могу просто настроить эти параметры, чтобы получить то, что мне нужно.

Другие вопросы по тегам