0

Scalaパーサーコンビネーターを使用する演習として、単純なWikiのようなマークアップパーサーを実装したいと思います。

これを少しずつ解決したいので、最初のバージョンで達成したいのは、単純なインラインリテラルマークアップです。

たとえば、入力文字列が次の場合:

This is a sytax test ``code here`` . Hello ``World``

出力文字列は次のようになります。

This is a sytax test <code>code here</code> . Hello <code>World</code>

私はを使用してこれを解決しようとしRegexParsersます、そしてこれが私が今やったことです:

import scala.util.parsing.combinator._
import scala.util.parsing.input._

object TestParser extends RegexParsers
{   
    override val skipWhitespace = false

    def toHTML(s: String) = "<code>" + s.drop(2).dropRight(2) + "</code>"

    val words = """(.)""".r
    val literal = """\B``(.)*``\B""".r ^^ toHTML

    val markup = (literal | words)*

    def run(s: String) = parseAll(markup, s) match {
        case Success(xs, next) => xs.mkString
        case _ => "fail"
    }
}

println (TestParser.run("This is a sytax test ``code here`` . Hello ``World``"))

<code>このコードでは、マークアップを1つだけ含む単純な入力が適切に機能します。次に例を示します。

This is a sytax test ``code here``.

なる

This is a sytax test <code>code here</code>.

しかし、上記の例で実行すると、次のようになります。

This is a sytax test <code>code here`` . Hello ``World</code>

これは、私が使用する正規表現が原因だと思います。

"""\B``(.)*``\B""".r

``ペア で任意の文字を許可しました。

``ネストできなかったものを制限してこの問題を修正する必要があるかどうかを知りたいですか?

4

3 に答える 3

2

欲張りでないマッチングに関するいくつかのドキュメントは次のとおりです。

http://www.exampledepot.com/egs/java.util.regex/Greedy.html

基本的に、それは最初の ``から始まり、世界の終わりにある``と一致する試合を取得するために可能な限り進んでいます。

?*の後に、最長の一致ではなく、可能な限り最短の一致を実行するように指示します。

もう1つのオプションは、[^ `] *(`を除くすべて)を使用することです。これにより、強制的に早期に停止します。

于 2011-12-04T03:53:47.007 に答える
0

正規表現パーサーについてはよくわかりませんが、単純な 1 ライナーを使用できます。

def addTags(s: String) =
  """(``.*?``)""".r replaceAllIn (
                    s, m => "<code>" + m.group(0).replace("``", "") + "</code>")

テスト:

scala> addTags("This is a sytax test ``code here`` . Hello ``World``")
res0: String = This is a sytax test <code>code here</code> . Hello <code>World</code>
于 2011-12-04T04:22:30.527 に答える
0

いくつかの試行錯誤の後、次の正規表現が機能しているように見えることがわかりました。

"""``(.)*?``"""
于 2011-12-04T02:49:47.370 に答える