0

\([''"]\)\(.\{-}\)\1正規表現をエスケープするにはどうすればよいですか?*test 次の関数で

:%s/.*/\=substitute(submatch(0),"\([''"]\)\(.\{-}\)\1","*test","g")/

最初の正規表現は各行の引用符の間のすべてに一致し、同じ行の2番目の正規表現に一致するものに置き換えます

ありがとう、ベスト

編集:例:

select "foo" as subject from table where [subject_test]=true
union
select "bar" as subject from table where [subject_test]=true

になる必要があります

select "foo" as subject from table where [subject_foo]=true
union
select "bar" as subject from table where [subject_bar]=true
4

4 に答える 4

2

私があなたの質問を正しく理解しているかどうかわかりません。

関数を使用するsubstitute()場合、たとえばを使用する場合とは別のパターンの規則があります:s///
これを参照してください::hsubstitute()
それからのいくつかの部分:

...
ただし、{pat}との照合は常に、「magic」オプションが設定され、「cpoptions」が空のように行われます(スクリプトを移植可能にするため)。'ignorecase'は引き続き関連します。「smartcase」は使用されません。
...
{sub}の一部のコードには特別な意味があることに注意してください|sub-replace-special|。たとえば、何かを「\ n」(2文字)に置き換えるには、「\\n」または「\n」を使用します。

特別な正規表現コードの使用方法は明確ではありませんが、パターン文字列に二重引用符を使用している場合は、二重バックスラッシュを使用する必要があります。これは文字を"\\"意味し\、と同じ'\'です。関数substitute()
を使用する場合、これらは同等である必要があります。 そして、私のお気に入りの( "very magic")を使用するので、いくつかの正規表現式をバックスラッシュする必要はありません。
'\([a-z]\)'
"\\([a-z]\\)"
\v
"\\v([a-z])"

あなたの例は次のようになります(あなたのパターンが正しいかどうかは考慮していません

substitute(submatch(0), '\v([''"])(.{-})\1', "*test", "g")
Or:
substitute(submatch(0), "\\v(['\"])(.{-})\\1", "*test", "g")

トリッキーな部分は、関数substitute()でパターンを文字列として使用していることです。これは、たとえば、コマンドラインで通常パターンを使用している場合の状況ではありません:s///


編集(これもOPによるコメントによる):
あなたの例の使用法を理解しているとは言えませんが、あなたの質問のようなexコマンドで修正しようとするのに抵抗できませんでした(私はしようとしています同時にVIMについて学びます)。これが機能するコマンドであり、希望する結果が得られますが、繰り返しになりますが、使用法がわかりません。
しかし、問題は、文字列で正規表現をエスケープする方法を学ぶことであるように思われます。「文字列」が常に置換するものの前にある場合(および「」ごとに
1つだけ置換する場合):test

:%s/\v"([^"]+)".*_\zstest/\1/g

説明

  • \zs=試合を開始、\v=「非常に魔法」を使用
  • "([^"]+)""の間の(最小1)を除くすべての文字を「一致」させます (「実際の一致」はまだ開始されていませんが、括弧内の一致はとにかくサブマッチ番号1になります)""
  • .*次の式までのすべての文字:
  • _\zstest「一致」_testしますが\zs、その後「実際の一致」を開始するので、それだけtestが代用されます。
  • /\1/サブマッチ番号1に置き換えます

変更これは「安全」ではありませんでした。(@ Kentの回答から)より長い一致を追加し、処理された行のみを確認し"<any characters>"ました。
「文字列」が置換するものの前または後にある場合

:g/\v"[^"]+"/y w | s/\v\[\w*_\zstest\ze\]/\=matchstr(@w, '\v"\zs[^"]+\ze"')/g

説明

  • \v="非常に魔法"
  • g/\v"[^"]+"次のような行を使用する"<some text>"
  • /y wregへのヤンクライン。w(getline()を使用する代わりに)
  • |もう1つのコマンドがあります
  • \zs=一致の開始、\ze=一致の終了(先読みなどを使用するよりも高速)
  • \w使用するのと同じ[0-9A-Za-z_]
  • \[\w*_\zstest\ze\]「一致」[<almost any characters>_test]ですが、代わりに使用する「実際の一致」test\zs\ze
  • matchstr(str, match)を返しmatchますstr
  • matchstr(@w, '\v"\zs[^"]+\ze"')"行の間および行から文字を取得します"(regを使用w
  • ...そしてそれを使用して一致したものを置き換えますtest
  • /g[<almost any characters>_test]行内のすべての出現に対してそれを行います
于 2013-02-17T15:44:55.163 に答える
1

これで大丈夫ですか?

%s/\[.\{-}_\zstest\ze\]/\=split(getline('.'), '"')[1]/

これも(あなたの例では)機能し、簡単です:

%s/\[subject_test\]/\="[subject_".split(getline("."),'"')[1]."]"/
于 2013-02-17T10:54:56.230 に答える
0

VimLでは、一重引用符で囲まれた文字列は円記号を補間しませんが、二重引用符で囲まれた文字列は円記号を補間します。

したがって、との違いに注意して:echo '\'ください:echo "\\"。あなたの例では、二重引用符を使用しましたが、魔法をオフにしていないので、たくさんの逃げ道があります。参照してください:help magic...私が知ったので\v、人々は私が周りにいるのがはるかに楽しいと私に言います。

于 2013-02-17T17:05:09.693 に答える
0

代替関数で使用している文字をエスケープするには、escape()

Escape the characters in {chars} that occur in {string} with a backslash.

Example: 
     :echo escape('c:\program files\vim', ' \')  
Results in:  
    c:\\program\ files\\vim

たとえば、を使用できますescape('\([''"]\)\(.\{-}\)\1','\')
これは次のように拡張されます。\\(['"]\\)\\(.\\{-}\\)\\1

于 2013-02-17T18:44:12.357 に答える