如何编写Clojure宏以从String创建正则表达式?

时间:2022-03-05 22:49:02

I'm creating a convenience macro. Part of the convenience is that a regular expression can be specified with just a String, rather than the #"re" notation.

我正在创建一个方便的宏。方便的一部分是只能用String指定正则表达式,而不是#“re”表示法。

The one part I can't figure out is how to get the macro to take the String and rewrite it as a Clojure regex (e.g., produce the #"re" notation). I think it's a syntax / escaping problem.

我无法弄清楚的一个部分是如何让宏取出String并将其重写为Clojure正则表达式(例如,产生#“re”表示法)。我认为这是一个语法/逃避问题。

My first naive attempt (pretending I only want the String-to-regex part):

我的第一次天真尝试(假装我只想要String-to-regex部分):

(defmacro mymac [mystr] `#~mystr)

Is it even possible to do what I'm trying to do? Or, is there an actual function to take a String and produce a regex, instead of using the # reader macro?

甚至可以做我想做的事情吗?或者,是否有一个实际的函数来获取String并生成一个正则表达式,而不是使用#reader宏?

Or should I just drop into Java and use java.util.regex.Pattern?

或者我应该放入Java并使用java.util.regex.Pattern?

4 个解决方案

#1


29  

There is a function for it: re-pattern

它有一个功能:重新模式

user=> (re-pattern "\\d+")
#"\d+"

#2


7  

To explain a bit more:

再解释一下:

#"" is a reader macro. It is resolved at read time by the reader. So there is no way to create a macro which expands into a reader macro, because the read phase is long gone. A macro returns the actual data structure representing the expanded code, not a string which is parsed again like eg. #define works in C.

#“”是一个读者宏。它在阅读时由读者解决。因此,没有办法创建一个扩展为读取器宏的宏,因为读取阶段早已不复存在。宏返回表示扩展代码的实际数据结构,而不是像例如那样再次解析的字符串。 #define在C中有效。

j-g-faustus' answer is the Right Way(tm) to go.

j-g-faustus的回答是正确的方法(tm)。

#3


0  

I may be misunderstanding the question, but doesn't this do what you want?

我可能误解了这个问题,但这不是你想做的吗?

user=> (. java.util.regex.Pattern compile "mystr")
#"mystr"

#4


0  

To match a string verbatim, ignoring special characters:

要逐字匹配字符串,请忽略特殊字符:

(defn to-regex [some-string]
  (re-pattern (java.util.regex.Pattern/quote some-string)))

Then ... will only match ..., not aaa or any other three letter combination.

然后......只会匹配......,而不是aaa或任何其他三个字母的组合。

#1


29  

There is a function for it: re-pattern

它有一个功能:重新模式

user=> (re-pattern "\\d+")
#"\d+"

#2


7  

To explain a bit more:

再解释一下:

#"" is a reader macro. It is resolved at read time by the reader. So there is no way to create a macro which expands into a reader macro, because the read phase is long gone. A macro returns the actual data structure representing the expanded code, not a string which is parsed again like eg. #define works in C.

#“”是一个读者宏。它在阅读时由读者解决。因此,没有办法创建一个扩展为读取器宏的宏,因为读取阶段早已不复存在。宏返回表示扩展代码的实际数据结构,而不是像例如那样再次解析的字符串。 #define在C中有效。

j-g-faustus' answer is the Right Way(tm) to go.

j-g-faustus的回答是正确的方法(tm)。

#3


0  

I may be misunderstanding the question, but doesn't this do what you want?

我可能误解了这个问题,但这不是你想做的吗?

user=> (. java.util.regex.Pattern compile "mystr")
#"mystr"

#4


0  

To match a string verbatim, ignoring special characters:

要逐字匹配字符串,请忽略特殊字符:

(defn to-regex [some-string]
  (re-pattern (java.util.regex.Pattern/quote some-string)))

Then ... will only match ..., not aaa or any other three letter combination.

然后......只会匹配......,而不是aaa或任何其他三个字母的组合。