単純なタグパーサー


9

これは寛容なHTMLパーサーのモデルです。HTMLを解析して属性を抽出する代わりに、このコードゴルフでは、タグパーサーは単純になります。

タグ構造を解析し、括弧で囲まれた形式を返す関数を記述します。開始タグは1つの小文字で構成され、終了タグは1つの大文字で構成されます。たとえば、やにaAbaAB解析さ(a)(b(a))れます<a></a><b><a></a></b>。もちろん、タグは並列してネストすることができます。

「時期尚早」の閉じたタグを処理する必要があります。たとえば、ではabcA、はA最も外側のを閉じるaので、に解析され(a(b(c)))ます。

余分な終了タグは単に無視されます:にaAB解析され(a)ます。

重複するタグは処理されません。たとえば、前の追加の終了タグのルール(-> ()+ (追加))によって、ではなくにabAB解析されます。(a(b))(a(b))(b)abABabA(a(b))B

入力に空白やその他の不正な文字がないと仮定します。

ライブラリの使用は許可されていません。

以下は、リファレンス実装とテストケースのリストです。

#!/usr/bin/python

def pars(inpu):
  outp = ""
  stac = []
  i = 0
  for x in inpu:
    lowr = x.lower()
    if x == lowr:
      stac.append(x)
      outp += "(" + x
      i = i + 1
    else:
      while len(stac) > 1 and stac[len(stac) - 1] != lowr:
        outp += ")"
        stac.pop()
        i = i - 1
      if len(stac) > 0:
        outp += ")"
        stac.pop()
        i = i - 1
  outp += ")" * i
  return outp

tests = [
  ("aAaAbB", "(a)(a)(b)"),
  ("abBcdDCA", "(a(b)(c(d)))"),
  ("bisSsIB", "(b(i(s)(s)))"),
  ("aAabc", "(a)(a(b(c)))"),
  ("abcdDA", "(a(b(c(d))))"),
  ("abcAaA", "(a(b(c)))(a)"),
  ("acAC", "(a(c))"),
  ("ABCDEFG", ""),
  ("AbcBCabA", "(b(c))(a(b))")
]

for case, expe in tests:
  actu = pars(case)
  print "%s: C: [%s] E: [%s] A: [%s]" % (["FAIL", "PASS"][expe == actu], case, expe, actu)

最短のコードが勝ちます。


他のコードゴルフと同様に、標準ライブラリが許可されています
Ming-Tang

長さやネストレベルに制限はありません
Ming-Tang

4
AbcBCabA(として解析する必要(b(c))(a(b))があります。このコードを除いてコードが短くなっている可能性があります。)などの終了タグでつながる入力のテストケースを追加する必要があります
。– MtnViewMark

回答:


1

Golfscript、54文字

{[]:|\{.96>{.|+:|;40\}{32+|?).')'*\|>:|;}if}%|,')'*}:$

テスト

;["aAaAbB" "abBcdDCA" "bisSsIB" "aAabc" "abcdDA" "abcAaA" "acAC" "aAB" "abAB" "AbcBCabA"]{.' '\$n}%

aAaAbBaAaAbB (a)(a)(b)
abBcdDCA (a(b)(c(d)))
bisSsIB (b(i(s)(s)))
aAabc (a)(a(b(c)))
abcdDA (a(b(c(d))))
abcAaA (a(b(c)))(a)
acAC (a(c))
aAB (a)
abAB (a(b))
AbcBCabA (b(c))(a(b))

6

Haskell、111文字

s@(d:z)§c|c>'^'=toEnum(fromEnum c-32):s++'(':[c]|d<'='=s|d==c=z++")"|1<3=(z++")")§c
p=tail.foldl(§)"$".(++"$")

これはハスケルにとってかなりゴルフだ。楽しい機能:スタックと累積出力は同じ文字列に保持されます!

テストケース:

> runTests 
Pass: aAbaAB parsed correctly as (a)(b(a))
Pass: abcA parsed correctly as (a(b(c)))
Pass: aAB parsed correctly as (a)
Pass: abAB parsed correctly as (a(b))
Pass: aAaAbB parsed correctly as (a)(a)(b)
Pass: abBcdDCA parsed correctly as (a(b)(c(d)))
Pass: bisSsIB parsed correctly as (b(i(s)(s)))
Pass: aAabc parsed correctly as (a)(a(b(c)))
Pass: abcdDA parsed correctly as (a(b(c(d))))
Pass: abcAaA parsed correctly as (a(b(c)))(a)
Pass: acAC parsed correctly as (a(c))
Pass: AbcBCabA parsed correctly as (b(c))(a(b))

  • 編集:(113→111)@FUZxxlによって提案されたパターンを使用

d:zに@パターンを使用すると、2つの文字を節約できます。
FUZxxl

4

TI-83 +用のZ80マシンコード、41バイト

これは、TI-83 +で実行されるz80 cpuの16進数マシンコードでの実装です。

11XXXX131AFE61380F6FE53E28CD9DB47DCD9DB4188EE1BDC03E29CD9DB4189BEF4504E5214CE1C9

XXXX(3〜6を含む)は、解析している文字列の16ビットアドレスから1バイトを引いたものです。

Z80-ASCIIでエンコード:

¹XX≤¯•⟙8𝑭o↥>(ˣïÑ}ˣïÑ≠á↑γ∊>)ˣïÑ≠Ì⬆︎E𝑤↥!₄L↑Φ

(概算。TI計算機には独自の文字セットがあるためです。)

THEことに注意してくださいAsmPrgm、IN THE ABOVE含まれていません


2

Windows PowerShell、142 146 147 152 156 169

{$s=''
-join([char[]]"$args "|%{if(90-ge$_){')'*(($x=$s.indexOf("$_".ToLower())+1)+$s.Length*!$x)
$s=$s.substring($x)}else{"($_"
$s="$_$s"}})}

注意事項:これは単なるスクリプトブロックです。必要に応じて、変数に割り当てたり、関数名を指定したりできます。また、最後と引数の前.または&前に配置して実行することもできます。最後のスペースを使用して、閉じられていないタグを終了します。

すべてのテストに合格します。テストスクリプト:

$tests = ("aAaAbB","(a)(a)(b)"),("abBcdDCA","(a(b)(c(d)))"),("bisSsIB","(b(i(s)(s)))"),("aAabc","(a)(a(b(c)))"),("abcdDA","(a(b(c(d))))"),("abcAaA", "(a(b(c)))(a)"),("acAC","(a(c))")
"function f " + ((gc ./tags.ps1)-join"`n") | iex
$tests | %{
    $result = f $_[0]
    ("FAIL: $($_[0]):$($_[1]) - $result", 'PASS')[$result -ceq $_[1]]
}

2

Python- 114 113 153 192 174 159文字

from sys import *
s="";c=a=argv[1]
for f in a:
 o=c.find;p=f.lower
 if '@'<f<'\\':
\td=o(f)-o(p())
\ts+=")"*d
\tc=(c[:o(p())]+c[o(f)+1:])
 else:s+=("("+f)
print s

pythonのインデントパーサーを悪用して、タブ全体に1つのスペース、2つのタブに5つのスペースを使用します。

編集1 -range()関数に不要なスペースを保存しました

編集2-不適切な解析文法、終端されていないタグを処理するように修正しました。

編集3-タグツリーのあいまいさによって「正しくない」解析が生成される可能性があったバグを修正しました。カウンターではなく、スタックベースの戦略を実装しました。

編集4 -s.findの名前をoに変更して、繰り返し呼び出すために使用される文字を保存しないようにします。f.lowerについても同じことを行いました。

編集5-スペース/タブハックを追加し、3文字節約しました。

編集6- ")" * dを優先してループを破棄しました。


1
代わりにord(f)...使用することができます'@'<f<'\\'あなたがチェックする必要がない場合'\\'は、使用できる']'代わりに
gnibbler

1
5つのスペースの代わりに単一のタブを使用できます。コードのマークアップはかかわらず、それを扱うことができないSO :(あなたのケースでは、単に完全に改行やスペース外に休暇を置くなど。。if ...:s+=")";c-=1else:s+="("+f;c+=1
gnibbler

1
for i in range(d):s+=")"として書き換えることができますs+=")"*d。そして、あなたは174文字を持っています。
cemper93

@cemper-その良い点。私は "_" * 80を一日中やっていて、ゴルフをしているときは忘れてしまいます...また、@ gnibblerに提案をありがとう!
2011年

実際には、以前に 174文字でした。159歳になりました。
cemper93
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.