0

我想实现一个简单的类似 Wiki 的标记解析器,作为使用 Scala 解析器组合器的练习。

我想一点一点地解决这个问题,所以这是我想在第一个版本中实现的:一个简单的内联文字标记。

例如,如果输入字符串是:

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>标记的更简单的输入可以正常工作,例如:

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

基本上它从第一个 `` 开始,并尽可能地获得匹配,它与世界末日的 `` 匹配。

通过放一个?在你的 * 之后,你告诉它做最短的匹配,而不是最长的匹配。

另一种选择是使用 [^`]* (除 ` 之外的任何内容),这将迫使它提前停止。

于 2011-12-04T03:53:47.007 回答
0

经过反复试验,我发现以下正则表达式似乎有效:

"""``(.)*?``"""
于 2011-12-04T02:49:47.370 回答
0

我不太了解正则表达式解析器,但您可以使用简单的 1-liner:

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 回答