我有一个相当简单的正则表达式,它在我的Ruby代码中工作得很好,但在我的Lisp代码中却不能工作。我只是尝试匹配一个URL (斜杠后面跟着一个单词,仅此而已)。下面是我在Ruby中使用的正则表达式:^\/\w*$
我希望它与"/"或"/foo"匹配,但不与"/foo/bar"匹配
我尝试过以下几种方法:
(cl-ppcre:scan "^/\w*$" "/") ;works
(cl-ppcre:scan "^/\w*$" "/foo") ;doesn't work!
(cl-ppcre:scan "^/\w*$" "/foo/bar") ;works, ie doesn't match有人能帮帮忙吗?
发布于 2018-12-27 15:27:48
缺省情况下,反斜杠()字符是single escape character:它可以防止对后面的字符进行任何特殊处理,因此可以使用它在字符串文字中包含双引号("),例如"\""。
因此,当您将文字字符串"^/\w*$"传递给cl-ppcre:scan时,实际传递的字符串将是"^/w*$",即只删除反斜杠。您可以通过评估将匹配的(cl-ppcre:scan "^/\w*$" "/w")来验证这一点。
要在正则表达式中包含反斜杠字符,需要像这样引用它:"^/\\w*$"。
如果您经常使用文字正则表达式,则所需的字符串引号可能会变得单调乏味且难以阅读。看看CL-INTERPOL中的一个库,它为Lisp阅读器添加了更好的正则表达式语法。
发布于 2018-12-28 01:43:46
如果您对正则表达式有疑问,也可以使用ppcre:parse-string进行检查
CL-USER> (ppcre:parse-string "^/\w*$")
(:SEQUENCE :START-ANCHOR #\/ (:GREEDY-REPETITION 0 NIL #\w) :END-ANCHOR)上面的内容告诉我们,反斜杠-w被解释为文字w字符。
将此表达式与您要使用的表达式进行比较:
CL-USER> (ppcre:parse-string "^/\\w*$")
(:SEQUENCE :START-ANCHOR #\/ (:GREEDY-REPETITION 0 NIL :WORD-CHAR-CLASS) :END-ANCHOR)返回值是一个表示正则表达式的树。实际上,您可以在CL-PPCRE需要正则表达式的任何地方使用相同的表示。尽管有点冗长,但这有助于将值组合到正则表达式中,而不必担心字符串嵌套或字符串中的特殊字符:
(defun maybe (regex)
`(:greedy-repetition 0 1 ,regex))
(defparameter *simple-floats*
(let ((digits '(:register (:greedy-repetition 1 nil :digit-class))))
(ppcre:create-scanner `(:sequence
(:register (:regex "[+-]?"))
,digits
,(maybe `(:sequence "." ,digits))))))在上面,点"."是按字面意思读取的,而不是正则表达式。这意味着您可以在纯字符串的正则表达式中使用转义字符来匹配像"(^.^)"或"[]"这样难以写入和读取的字符串。通过使用(:regex "...")表达式,您可以将正则表达式作为字符串。
CL-PPCRE有一个优化,在加载时使用load-time-value预先计算常量正则表达式。如果您的正则表达式不是微不足道的常量,则可能不会应用该优化,因此您可能希望将自己的扫描器包装在load-time-value表单中。只需确保您在加载时准备好了足够的定义,比如辅助maybe函数。
https://stackoverflow.com/questions/53939960
复制相似问题