2017-06-01 5 views
2

私はWikiマークアップ言語で書かれたテーブルを解析する必要があるPerlプログラムを書いています。テーブル構文では、パイプ文字 '|'が使用されます。列を区切る。ハイパーリンクは、パイプ文字を含んでいてもよいこと文字列を分割し、引用符で囲まれた区切り文字を無視するregexp

[[wiki:path:to:page|Page Title]] or 
[[wiki:path:to:page]] 

| row 1 cell 1 |row 1 cell 2 | row 1 cell 3| 
| row 2 cell 1 | row 2 cell 2 |row 2 cell 3| 

細胞は、その構文によって示されるゼロ以上のハイパーリンクを含むことができます。ただし、ここでは[[..]]括弧で "引用"されています。

ハイパーリンク構文はネストできません。

一致し、これらのテーブル行のそれぞれの最初のセルをキャプチャするために

| Potatoes [[path:to:potatoes]]   | Daisies   | 
| Kiki fruit [[path:to:kiwi|Kiwi Fruit]] |    Lemons| 

は、私が試した:

qr{\|      # match literal pipe 
    (.*?     # non-greedy zero or more chars 
     (?:\[\[.*?\]\]) # a hyperlink 
    .*?)     # non-greedy zero or more chars 
    \|}x     # match terminating pipe 

それは働いた、と$ 1がセルの内容を含んでいました。

qr{\|      # match literal pipe 
    (.*?     # non-greedy zero or more chars 
     (?:\[\[.*?\]\])? # <-- OPTIONAL hyperlink 
    .*?)     # non-greedy zero or more chars 
    \|}x     # match terminating pipe 

これは働いたが、

| Kiki fruit [[path:to:kiwi|Kiwi Fruit]] |    Lemons| 

を解析するとき、私は唯一の

Kiki fruit [[path:to:kiwi 
を得た:

その後、

| Potatoes   | Daisies   | 

に一致するように、私は、ハイパーリンクはオプション作ってみました

明らかに、オプションを指定すると、ハイパーリンクパターンを無視し、埋め込みパイプを列区切り文字として扱うことにしました。

ここで私は立ち往生しています。そして、私は依然として、セル内でハイパーリンクが2回以上出現する可能性、または後続のパイプを次の反復時に先導パイプに戻すことをまだ扱っていません。

Perlのsplit関数でregexpを使う必要はありません。もし簡単であれば、自分で分割ループを書くことができます。私は似たような多くの質問をしているのを見ていますが、誰もこの問題を十分には考慮していないようです。

+0

パイプ文字にテキストを分割すると、名前が変更されたリンク、リンク、またはリンクが含まれていないと内容を解析できないという問題があります。そうですか? – Borodin

+0

いいえ、名前が変更されたリンクが含まれていると、テキスト(表の行全体のマークアップ)を列に分割できません。 – Chap

答えて

1
$ perl -MRegexp::Common -E '$_=shift; while (
    /\| # beginning pipe, and consume it 
    ( # capture 1 
    (?: # inside the pipe we will do one of these: 
     $RE{balanced}{-begin=>"[["}{-end=>"]]"} # something with balanced [[..]] 
     |[^|] # or a character that is not a pipe 
    )* # as many of those as necessary 
) # end capture one 
    (?=\|) # needs to go to the next pipe, but do not consume it so g works 
    /xg 
) { say $1 }' '| Kiki fruit [[path:to:kiwi|Kiwi Fruit]] |    Lemons|' 
Kiki fruit [[path:to:kiwi|Kiwi Fruit]] 
      Lemons 

これはあなたが探しているものを抽出するようです。しかし、私はあなたがこの言語のための適切なパーサーでより良いと思う。私はcpanに何かがなかったら驚いたでしょうが、そうでなくても、あなたが扱う必要のあるテーブルにもっと奇妙なものをつくるようになると、特にパーサーを書く方がずっと良いかもしれません。

+0

以下に述べるように、CPAN以降でPerlソリューションを見つけることができませんでした。 – Chap

+0

この回答は、リンクのないセルや複数のリンクを持つセルも処理します。私にとって重要なことは、(1)Regexp :: Commonを使用し、(2)パイプ以外の文字とバランスの取れた表現の両方を0回以上繰り返す「アトミック」代替として扱うことです。シンプル。 – Chap

関連する問題