0

私は2つの潜在的な入力形式を持つことができる関数を書いています:

  1. This is {a {string}}
  2. This {is} a {string}

中括弧で囲まれた部分文字列を「タグ」と呼びます。文字列には任意の数のタグを含めることができ、任意の深さでネストすることができます。

タグを取得するための正規表現を作成しようとしましたが、これはもちろんネストされたタグで失敗し、 を取得し{a {string}、2 番目の中括弧がありません。私はそれを再帰的な問題として見ることができますが、あまりにも長い間間違った答えを見つめていると、本当に明白なものを見ることができなくなったように感じます.

潜在的なタグをパーツに分けて、処理および置換できるようにするにはどうすればよいですか?

より複雑なバージョン

def parseTags( oBody, szText )


  if szText.match(/\{(.*)\}/)
    szText.scan(/\{(.*)\}/) do |outers|
      outers.each do |blah|
        if blah.match(/(.*)\}(.*)\{(.*)/)
          blah.scan(/(.*)\}(.*)\{(.*)/) do |inners|
            inners.each do |tags|
              szText = szText.sub("\{#{tags}\}", parseTags( oBody, tags ))
            end
          end
        else
          szText = szText.sub("\{#{blah}\}", parseTags( oBody, blah ))
        end
      end
    end
  end
  if szText.match(/(\w+)\.(\w+)(?:\.([A-Za-z0-9.\[\]": ]*))/)
    func = $1+"_"+$2
    begin
      szSub = self.send func, oBody, $3
    rescue Exception=>e
      szSub = "{Error: Function #{$1}_#{$2} not found}"
      $stdout.puts "DynamicIO Error Encountered: #{e}"
    end
    szText = szText.sub("#{$1}.#{$2}#{$3!=nil ? "."+$3 : ""}", szSub)
  end
  return szText
end

これは、いじりすぎた結果です。きれいではありませんが、「1」に似たケースではうまくいきました -{help.divider.red.sys.["{pc.login}"]}は に置き換えられ---------------[ Duwnel ]---------------ます。ただし、{pc.attr.str.dotmode} {ansi.col.red}|{ansi.col.reset} {pc.attr.pre.dotmode} {ansi.col.red}|{ansi.col.reset} {pc.attr.int.dotmode}赤のランダムな筋と欠落したテキストの見本があり、見事に内破します。

説明すると、マークが付いているものはすべて{ansi.col.red}ANSI 赤コードをマークし、リセットはカラー ブロックをエスケープし、{pc.attr.XXX.dotmode}1 から 10 までの数字を「o」で表示します。

4

2 に答える 2

1

より複雑な正規表現をこの問題に当てはめるのではなく、Ruby の文法ベースの構文解析エンジンの 1 つを調べることをお勧めします。これらのほとんどで、再帰的でネストされた文法を設計することが可能です。

parsletあなたの問題を始めるのに良い場所かもしれません。erb に似た例は、ネストを示していませんが、ニーズに最も近いかもしれません: https://github.com/kschiess/parslet/blob/master/example/erb.rb

于 2013-05-30T22:43:07.767 に答える