the output of the replacement is leaving the lines unchanged
Это указывает на то, что ваше регулярное выражение не соответствует входным данным, поэтому давайте сделаем шаг назад и посмотрим, сможем ли мы получить минимальное работающее регулярное выражение:
perl -w -pe "s/INSERT INTO currency (name, code, symbol) VALUES ('(.*?)', '(.*?)', '(.*?)');//" currencies.rb
> INSERT INTO currency (name, code, symbol) VALUES ('Baht', 'THB', '?');
Просто удалили замену, и неудивительно, что нет никакой разницы с тем, что вы получили сначала, это не соответствует вводу.
Теперь последняя часть вашего регулярного выражения ('(.*?)', '(.*?)', '(.*?)')
содержит много символов, которые имеют особое значение в регулярном выражении, так что давайте удалим их и посмотрим, работает ли это:
perl -w -pe "s/INSERT INTO currency (name, code, symbol) VALUES.*;//" currencies.rb
> INSERT INTO currency (name, code, symbol) VALUES ('Baht', 'THB', '?');
Все еще не соответствует, теперь единственными специальными символами являются ()
, которые, вероятно, следует экранировать:
perl -w -pe "s/INSERT INTO currency \(name, code, symbol\) VALUES.*;//" currencies.rb
>
Да, это соответствует -наш ввод был сопоставлен и удален, поэтому давайте снова добавим конечный бит, на этот раз также экранируя другие ()
s:
perl -w -pe "s/INSERT INTO currency \(name, code, symbol\) VALUES \('(.*?)', '(.*?)', '(.*?)'\);//" currencies.rb
>
Все еще совпадает, так что давайте снова добавим замену:
perl -w -pe "s/INSERT INTO currency \(name, code, symbol\) VALUES \('(.*?)', '(.*?)', '(.*?)'\);/currency = Currency.find_by_iso(\$&) || Currency.new(:code => '\$&')/" currencies.rb
> currency = Currency.find_by_iso(INSERT INTO currency (name, code, symbol) VALUES ('Baht', 'THB', '?');) || Currency.new(:code => 'INSERT INTO currency (name, code, symbol) VALUES ('Baht', 'THB', '?');')
Хм, кажется, это неправильная часть. Это связано с тем, что & заменяется всем совпадающим выражением, а не одной подгруппой, вместо которой вы хотите $1
, $2
и т. д.:
perl -w -pe "s/INSERT INTO currency \(name, code, symbol\) VALUES \('(.*?)', '(.*?)', '(.*?)'\);/currency = Currency.find_by_iso(\$2) || Currency.new(:code => '\$2')/" currencies.rb
> currency = Currency.find_by_iso(THB) || Currency.new(:code => 'THB')
Почти готово, отсутствуют некоторые кавычки -нам также не нужны совпадения двух других подгрупп, поэтому давайте удалим их:
perl -w -pe "s/INSERT INTO currency \(name, code, symbol\) VALUES \('.*?', '(.*?)', '.*?'\);/currency = Currency.find_by_iso('\$1') || Currency.new(:code => '\$1')/" currencies.rb
> currency = Currency.find_by_iso('THB') || Currency.new(:code => 'THB')
Вот и все, именно то, что мы хотели.
При столкновении со сложным регулярным выражением, которое кажется неработающим, обычно проблема связана с некоторыми специальными символами, она варьируется от языка к языку и от инструмента к инструменту -иногда нужно экранировать, иногда нет. Всегда полезно начинать с удаления этих символов с более простыми альтернативами, пока вы не получите регулярное выражение, которое соответствует части вашего ввода,даже если это не совсем та часть, которую вы хотите -, постепенно расширяйте ее оттуда, пока она не сломается, или вы не получите то, что хотите. Если вы обнаружите, что это не так, вам следует прочитать документацию по языку/инструменту, который вы используете, чтобы выяснить синтаксис, который вы на самом деле ищете.
Вы можете bind
виджеты vi-{back,for}ward-blank-word
на Ctrl+{влево, вправо}`:
bindkey $'\E[1;5D' vi-backward-blank-word
bindkey $'\E[1;5C' vi-forward-blank-word
или переопределить {back,for}ward-word
виджеты, чтобы использовать другой WORDCHARS
(, чтобы это повлияло на другие привязки (, такие как Alt+{B,F} ), которые используют эти виджеты):
WORDCHARS='~!#$%^&*(){}[]<>?.+;-'
MOTION_WORDCHARS='~!#$%^&*(){}[]<>?.+;-/'
''{back,for}ward-word() WORDCHARS=$MOTION_WORDCHARS zle.$WIDGET
zle -N backward-word
zle -N forward-word
См. такжеinfo zsh select-word-style
структуру для динамического выбора стилей слов .
Вы также можете использовать его для выбора разных стилей слов для разных виджетов, например:
autoload -U select-word-style
zle -N select-word-style
bindkey '\ez' select-word-style
WORDCHARS='~!#$%^&*(){}[]<>?.+;-' # for the "normal" style
select-word-style normal
zstyle ':zle:*ward-word' word-style space
zstyle ':zle:backward-kill-word' word-style space
Вы получите стиль слова на основе «пробела» -для виджетов *ward-word
и backward-kill-word
и всего, что выбрано с помощью Alt+Z , изначально «обычный»,$WORDCHARS
-на основе стиля слова для других виджетов слова.