【问题标题】:Matching end-of-line with CL-PPCRE用 CL-PPCRE 匹配行尾
【发布时间】:2018-12-27 05:01:40
【问题描述】:

我有一个相当简单的正则表达式,它在我的 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

有人可以帮忙吗?

【问题讨论】:

    标签: regex common-lisp cl-ppcre


    【解决方案1】:

    默认情况下,反斜杠 (\) 字符是 single escape character:它防止对其后面的字符进行任何特殊处理,因此它可以用于在其中包含双引号 (")像 "\"" 这样的字符串文字。

    因此,当您将文字字符串"^/\w*$" 传递给cl-ppcre:scan 时,传递的实际字符串将是"^/w*$",即反斜杠将被删除。您可以通过评估 (cl-ppcre:scan "^/\w*$" "/w") 来验证这一点,这将匹配。

    要在正则表达式中包含反斜杠字符,您需要像这样引用它:"^/\\w*$"

    如果您经常使用文字正则表达式,则所需的字符串引用可能会变得乏味且难以阅读。查看CL-INTERPOL 的库,该库为 Lisp 阅读器添加了更好的正则表达式语法。

    【讨论】:

    • 是的!做到了!谢谢hans23!
    【解决方案2】:

    如果您对自己的正则表达式有疑问,也可以通过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 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 2013-06-22
      相关资源
      最近更新 更多