如何使用CASE或CORE.Match使用重新匹配

发布于 2025-01-22 00:01:20 字数 759 浏览 1 评论 0原文

我正在尝试在Clojure中实现模式匹配。我的偏爱是使用core.Match在给定的正则表达式模式上匹配。我尝试了一下:

(defn markdown->html [markdown-line]
  (match [markdown-line]
    [(boolean (re-matches #"#\s+\w+" markdown-line))] (str "<h1>")))

这甚至无法正确编译。我透露了一个案例的条件:

(defn markdown->html [markdown-line]
  (case markdown-line
    (boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))

但是,当我使用此调用时,这并没有给我预期的结果:(markdown-&gt; html“#foo”)>

但是,这可行!

(defn markdown->html [markdown-line]
  (if
    (boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))

对于上面的所有测试,我会像这样调用该功能:(Markdown-&gt; html“#foo”)

有人知道我在做什么错吗?

I am trying to implement pattern-matching in Clojure. My preference is to use core.match to match on a given regex pattern. I tried this:

(defn markdown->html [markdown-line]
  (match [markdown-line]
    [(boolean (re-matches #"#\s+\w+" markdown-line))] (str "<h1>")))

This does not even compile properly. I pivoted to a case conditional:

(defn markdown->html [markdown-line]
  (case markdown-line
    (boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))

However, that did not give me the expected results when I invoke it with this: (markdown->html "# Foo")

However, this works!

(defn markdown->html [markdown-line]
  (if
    (boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))

For all the tests above, I am invoking the function like so: (markdown->html "# Foo")

Does anyone know what I am doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

诗笺 2025-01-29 00:01:20

请参阅

未评估测试剂。他们必须是编译时间
文字,不必引用。

例如:

(case 'y
  y "y"
  c "c"
  (x z) "x or z"
  (a b) "a or b"
  "default")

clojure.core.core.match/match是相似的,所以我想说这两个都是错误的工具。

如果您要编写将github markdown转换为html的功能,请检查 可以帮助您:

(clojure.string/replace "# Foo bar
# Biz baz" #"#\s+([\w ]*)" (fn [[result group]] (str "<h1>" group "</h1>")))

=> "<h1>Foo bar</h1>\n<h1>Biz baz</h1>"

甚至更好,使用$组:

(clojure.string/replace "# Foo bar
# Biz baz" #"#\s+([\w ]*)" "<h1>$1</h1>")

=> "<h1>Foo bar</h1>\n<h1>Biz baz</h1>"

顺便说一句,可以这样改进您的示例:

(defn markdown->html [markdown-line]
  (when (re-matches #"#\s+\w+" markdown-line) "<h1>"))

(markdown->html "# Foo")
=> "<h1>"

如果缺少 else 分支,所以更好时;您不必使用boolean,因为falsenil被视为逻辑false,任何其他值都是逻辑的,没有将一个字符串包裹在str中的原因。

编辑:标题功能&lt; h1&gt; - &lt; h6&gt;

(def text "# Foo bar
## Biz baz
### Foo baz
## Biz foo")

(clojure.string/replace text
                        #"(#{1,6})\s+([\w ]*)"
                        (fn [[result group1 group2]]
                          (let [tag (str "h" (count group1) ">")]
                            (str "<" tag group2 "</" tag))))

=> "<h1>Foo bar</h1>\n<h2>Biz baz</h2>\n<h3>Foo baz</h3>\n<h2>Biz foo</h2>"

See the docs for case:

The test-constants are not evaluated. They must be compile-time
literals, and need not be quoted.

For example:

(case 'y
  y "y"
  c "c"
  (x z) "x or z"
  (a b) "a or b"
  "default")

And clojure.core.match/match is similar, so I'd say both are wrong tool for your problem.

If you're trying to write function for converting Github markdown to HTML, check clojure.string/replace, which can help you:

(clojure.string/replace "# Foo bar
# Biz baz" #"#\s+([\w ]*)" (fn [[result group]] (str "<h1>" group "</h1>")))

=> "<h1>Foo bar</h1>\n<h1>Biz baz</h1>"

Or even better, using $ for group:

(clojure.string/replace "# Foo bar
# Biz baz" #"#\s+([\w ]*)" "<h1>$1</h1>")

=> "<h1>Foo bar</h1>\n<h1>Biz baz</h1>"

By the way, your example can be improved like this:

(defn markdown->html [markdown-line]
  (when (re-matches #"#\s+\w+" markdown-line) "<h1>"))

(markdown->html "# Foo")
=> "<h1>"

If is missing else branch, so when is better; you don't have to use boolean, because false or nil are considered as logical false and any other value is logical true and there is no reason to wrap one string in str.

EDIT: Function for headers <h1> - <h6>:

(def text "# Foo bar
## Biz baz
### Foo baz
## Biz foo")

(clojure.string/replace text
                        #"(#{1,6})\s+([\w ]*)"
                        (fn [[result group1 group2]]
                          (let [tag (str "h" (count group1) ">")]
                            (str "<" tag group2 "</" tag))))

=> "<h1>Foo bar</h1>\n<h2>Biz baz</h2>\n<h3>Foo baz</h3>\n<h2>Biz foo</h2>"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文