如何使用重新匹配大小写或 core.match
How to use re-matches with case or core.match
我正在尝试在 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->html "# Foo")
但是,这有效!
(defn markdown->html [markdown-line]
(if
(boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))
对于上面的所有测试,我是这样调用函数的:(markdown->html "# Foo")
有谁知道我做错了什么吗?
查看 case
的文档:
The test-constants are not evaluated. They must be compile-time
literals, and need not be quoted.
例如:
(case 'y
y "y"
c "c"
(x z) "x or z"
(a b) "a or b"
"default")
和 clojure.core.match/match
相似,所以我想说两者都不是解决您的问题的工具。
如果您正在尝试编写将 Github markdown 转换为 HTML 的函数,请检查 clojure.string/replace
,这可以帮助您:
(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></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>"
If
缺少 else 分支,所以 when
更好;您不必使用 boolean
,因为 false
或 nil
被认为是逻辑假,任何其他值都是逻辑真,没有理由将一个字符串包装在 [=24 中=].
编辑: 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>"
我正在尝试在 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->html "# Foo")
但是,这有效!
(defn markdown->html [markdown-line]
(if
(boolean (re-matches #"#\s+\w+" markdown-line)) (str "<h1>")))
对于上面的所有测试,我是这样调用函数的:(markdown->html "# Foo")
有谁知道我做错了什么吗?
查看 case
的文档:
The test-constants are not evaluated. They must be compile-time literals, and need not be quoted.
例如:
(case 'y
y "y"
c "c"
(x z) "x or z"
(a b) "a or b"
"default")
和 clojure.core.match/match
相似,所以我想说两者都不是解决您的问题的工具。
如果您正在尝试编写将 Github markdown 转换为 HTML 的函数,请检查 clojure.string/replace
,这可以帮助您:
(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></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>"
If
缺少 else 分支,所以 when
更好;您不必使用 boolean
,因为 false
或 nil
被认为是逻辑假,任何其他值都是逻辑真,没有理由将一个字符串包装在 [=24 中=].
编辑: 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>"