3

計画:

ウィキペディアのローマ執政官のリストを取得し、データをCSVに入れて、執政官の観点からさまざまな世代の上昇と下降のグラフを作成できるようにします

データソースの例:

509,L. Iunius Brutus,L. Tarquinius Collatinus
suff.,Sp. Lucretius Tricipitinus,P. Valerius Poplicola
suff.,M. Horatius Pulvillus,
508,P. Valerius Poplicola II,T. Lucretius Tricipitinus
507,P. Valerius Poplicola III,M. Horatius Pulvillus II

Vim検索:

/\v(\d+|suff\.),((\w+\.=) (\w+)(\s\w+)=(\s\w+)=(\s[iv]+)=(\s\(.{-}\))=,=){,2}

だから本質的に:

  1. 最初の年を見つけます(または執政官の指示):(\d+|suff\.)
  2. 次のグループ化(これを外部グループと呼びましょう)は、最大2回まで見つける必要があります。(outer group){,2}
  3. これらの2つの外部グループのそれぞれについて、次を見つけます。
    1. プラエノーメン、オプションのピリオド付き(これが存在しない場合もあります):(\w+.=)
    2. だれも:(\w+)
    3. オプションのコグノーメン(以下のすべてのように、スペースを含みます):(\s\w+)=
    4. オプションのアグノーメン:(\s\w+)=
    5. オプションの反復(彼が領事を務めたn回目を示します)。データソースには8回を超える反復がありません(したがって、IとVで十分です)。(\s[iv]+)=
    6. 「シシニウス(サビヌス?)」のようなオプションの説明文:(\s\(.{-}\))=

(最後のコンマは行の終わりなのでオプションです。)

したがって、バックリファレンスは次のようになります。

\1: year or suffect
\2: the entire second outer group
\3: Praenomen of second outer group (same with all below)
\4: Nomen
\5: Cognomen
\6: Agnomen
\7: Iteration
\8: Explanatory note

問題は、その最初の外側のグループをキャプチャする方法がわからないことです。これは、\2と\3- \ 8の参照が、その2番目の外部グループを見ると上書きされるようなものです。

この置換の使用:

:%s//1:{\1}^I2:{\2}^I3:{\3}^I4:{\4}^I5:{\5}^I6:{\6}^I7:{\7}^I8:{\8}^I9:{\9} 

私はこの出力を取得します:

1:{509} 2:{L. Tarquinius Collatinus}    3:{L.}  4:{Tarquinius}  5:{ Collatinus} 6:{}    7:{}    8:{}    9:{}
1:{suff.}   2:{P. Valerius Poplicola}   3:{P.}  4:{Valerius}    5:{ Poplicola}  6:{}    7:{}    8:{}    9:{}
1:{suff.}   2:{M. Horatius Pulvillus,}  3:{M.}  4:{Horatius}    5:{ Pulvillus}  6:{}    7:{}    8:{}    9:{}
1:{508} 2:{T. Lucretius Tricipitinus}   3:{T.}  4:{Lucretius}   5:{ Tricipitinus}   6:{ II} 7:{}    8:{}    9:{}
1:{507} 2:{M. Horatius Pulvillus II}    3:{M.}  4:{Horatius}    5:{ Pulvillus}  6:{ II} 7:{}    8:{}    9:{}

最初の外部グループ内のそれらのグループにアクセスできません。私はそれらが上書きされていると思います:それらは上書きされていますか?もしそうなら、これを回避する方法はありますか?

編集:元のタイトルVim正規表現(または互換性のある正規表現):外部グループが繰り返される場合に(グループ内の)グループを参照する方法は?

4

2 に答える 2

4

私はそれをサブステップに分解し、すべてのnormal(しゃれを意図した)方法ではなく、vim関数を使用します:

/\v(.{-}),(.{-}),(.*)

私がしたことを参照してください?はるかにシンプルで明確になりました

編集少し怠惰にならないように、少なくとも3つのサブ文字列に分割し、それらをタブで区切るヘルパー関数を定義しましょう。

function! Consul(s)        
    return join((split(a:s) + ["","",""])[0:2], "\t")
endf

ここで、置換を(SOのみの改行)に減らします。

%s/\v(.{-}),(.{-}),(.*)/\=join(
  [submatch(1), Consul(submatch(2)), Consul(submatch(3))], "\t")/g

あなたの入力でその美しさを実行すると、

509 L.  Iunius  Brutus  L.  Tarquinius  Collatinus
suff.   Sp. Lucretius   Tricipitinus    P.  Valerius    Poplicola
suff.   M.  Horatius    Pulvillus           
508 P.  Valerius    Poplicola   T.  Lucretius   Tricipitinus
507 P.  Valerius    Poplicola   M.  Horatius    Pulvillus

タブで区切られた列を好みに合わせてさらに装飾するのは、非常に簡単なステップになると確信しています。追加するかもしれませんが、今のところ、私が考えることができる最も簡単なことは次のとおりです。

:%s/\v(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})\t(.{-})$/1:{\1}\t2:{\2}\t3:{\3}\t4:{\4}\t5:{\5}\t6:{\6}\t7:{\7}/g

結果:

1:{509} 2:{L.}  3:{Iunius}  4:{Brutus}  5:{L.}  6:{Tarquinius}  7:{Collatinus}
1:{suff.}   2:{Sp.} 3:{Lucretius}   4:{Tricipitinus}    5:{P.}  6:{Valerius}    7:{Poplicola}
1:{suff.}   2:{M.}  3:{Horatius}    4:{Pulvillus}   5:{}    6:{}    7:{}
1:{508} 2:{P.}  3:{Valerius}    4:{Poplicola}   5:{T.}  6:{Lucretius}   7:{Tricipitinus}
1:{507} 2:{P.}  3:{Valerius}    4:{Poplicola}   5:{M.}  6:{Horatius}    7:{Pulvillus}
于 2012-02-08T22:34:30.703 に答える
3

はい、繰り返し内のグループのキャプチャは、最新の一致した値に上書きされます。リンク先ページの下部にある「繰り返しと後方参照」セクションによると、次のようになります。

正規表現エンジンは、正規表現の後方参照を永続的に置き換えるわけではありません。使用する必要があるたびに、後方参照に保存された最後の一致が使用されます。括弧をキャプチャして新しい一致が見つかった場合、以前に保存された一致が上書きされます。

特定の数のキャプチャグループを明示的に書き出す必要があります。

私はvimの正規表現エンジンに特に精通していないので、ここに簡単な例を示します。
あなたのテキストがであるとしましょうabc 12 345 6789 xyz

# with repetition
/^\w+( \d+){1,3} \w+$/

# yields:
# 0: abc 12 345 6789 xyz
# 1:  6789

# -----
# writing out each subpattern
/^\w+( \d+)( \d+)?( \d+)? \w+$/

# yields:
# 0: abc 12 345 6789 xyz
# 1:  12
# 2:  345
# 3:  6789

{1,3}の繰り返し範囲で、2番目と3番目を( \d+)オプションにしたことに注意してください?

于 2012-02-08T21:57:19.843 に答える