更正正则表达式“\[([a-zA-Z0-9_-]+)]”
Correcting the regex "\[([a-zA-Z0-9_-]+)]"
以下 cl-ppcre 正则表达式生成错误:
(ppcre:scan-to-strings "\[([a-zA-Z0-9_-]+)]" "[has-instance]")
debugger invoked on a CL-PPCRE:PPCRE-SYNTAX-ERROR in thread
#<THREAD "main thread" RUNNING {10010B0523}>:
Expected end of string. at position 16 in string "[([a-zA-Z0-9_-]+)]"
我期望的 return 值是:
“[has-instance]”
#(“has-instance”)
为了得到括号内的字符串。有人可以提供正则表达式更正吗?谢谢
转义符(反斜杠)只转义自身和双引号(§2.4.5 Double-Quote):
If a single escape character is seen, the single escape character is discarded, the next character is accumulated, and accumulation continues.
这意味着:
"\[([a-zA-Z0-9_-]+)]"
被解析为与以下相同,其中不存在反斜杠:
"[([a-zA-Z0-9_-]+)]"
CL-PPCRE 实现的 PCRE 语法将左方括号理解为字符 classes 的特殊语法,并在下一个右括号处结束。
因此,上面的内容是 class:
[([a-zA-Z0-9_-]
对应的正则表达式树为:
CL-USER> (ppcre:parse-string "[([a-zA-Z0-9_-]")
(:CHAR-CLASS #\( #\[ (:RANGE #\a #\z) (:RANGE #\A #\Z) (:RANGE #[=13=] #) #\_ #\-)
特别注意里面的左括号是按字面意思对待的。当解析器遇到上述片段后的右括号时,它将其解释为寄存器组的结尾,但没有启动这样的组,因此在字符串的第 16 位出现错误消息。
为避免将括号视为字符 class,它必须在字符串中以文字反斜杠开头,正如您尝试做的那样,但为了这样做,您必须 写入两个反斜杠字符:
CL-USER> (ppcre:parse-string "\[([a-zA-Z0-9_-]+)]")
(:SEQUENCE #\[
(:REGISTER
(:GREEDY-REPETITION 1 NIL
(:CHAR-CLASS (:RANGE #\a #\z) (:RANGE #\A #\Z) (:RANGE #[=14=] #) #\_ #\-)))
#\])
右方括号不需要反斜杠。
我鼓励您使用树形形式在 Lisp 中编写正则表达式,并在提高清晰度时使用 :regex
项:它避免了必须处理转义带来的那种问题。例如:
CL-USER> (ppcre:scan-to-strings
'(:sequence "[" (:register (:regex "[a-zA-Z0-9_-]+")) "]")
"[has-instance]")
"[has-instance]"
#("has-instance")
- 两次转义方括号。
- 你也忘了 (double) 转义右括号。
(cl-ppcre:scan-to-strings "\[([a-zA-Z0-9_-]+)\]" "[has-instance]")
;; "[has-instance]" ;
;; #("has-instance")
对于 common lisp 的新手,您可以使用 quicklisp 导入 cl-ppcre
:
(load "~/quicklisp/setup.list") ;; adjust path to where you installed your quicklisp
(ql:quickload :cl-ppcre)
以下 cl-ppcre 正则表达式生成错误:
(ppcre:scan-to-strings "\[([a-zA-Z0-9_-]+)]" "[has-instance]")
debugger invoked on a CL-PPCRE:PPCRE-SYNTAX-ERROR in thread
#<THREAD "main thread" RUNNING {10010B0523}>:
Expected end of string. at position 16 in string "[([a-zA-Z0-9_-]+)]"
我期望的 return 值是:
“[has-instance]”
#(“has-instance”)
为了得到括号内的字符串。有人可以提供正则表达式更正吗?谢谢
转义符(反斜杠)只转义自身和双引号(§2.4.5 Double-Quote):
If a single escape character is seen, the single escape character is discarded, the next character is accumulated, and accumulation continues.
这意味着:
"\[([a-zA-Z0-9_-]+)]"
被解析为与以下相同,其中不存在反斜杠:
"[([a-zA-Z0-9_-]+)]"
CL-PPCRE 实现的 PCRE 语法将左方括号理解为字符 classes 的特殊语法,并在下一个右括号处结束。 因此,上面的内容是 class:
[([a-zA-Z0-9_-]
对应的正则表达式树为:
CL-USER> (ppcre:parse-string "[([a-zA-Z0-9_-]")
(:CHAR-CLASS #\( #\[ (:RANGE #\a #\z) (:RANGE #\A #\Z) (:RANGE #[=13=] #) #\_ #\-)
特别注意里面的左括号是按字面意思对待的。当解析器遇到上述片段后的右括号时,它将其解释为寄存器组的结尾,但没有启动这样的组,因此在字符串的第 16 位出现错误消息。
为避免将括号视为字符 class,它必须在字符串中以文字反斜杠开头,正如您尝试做的那样,但为了这样做,您必须 写入两个反斜杠字符:
CL-USER> (ppcre:parse-string "\[([a-zA-Z0-9_-]+)]")
(:SEQUENCE #\[
(:REGISTER
(:GREEDY-REPETITION 1 NIL
(:CHAR-CLASS (:RANGE #\a #\z) (:RANGE #\A #\Z) (:RANGE #[=14=] #) #\_ #\-)))
#\])
右方括号不需要反斜杠。
我鼓励您使用树形形式在 Lisp 中编写正则表达式,并在提高清晰度时使用 :regex
项:它避免了必须处理转义带来的那种问题。例如:
CL-USER> (ppcre:scan-to-strings
'(:sequence "[" (:register (:regex "[a-zA-Z0-9_-]+")) "]")
"[has-instance]")
"[has-instance]"
#("has-instance")
- 两次转义方括号。
- 你也忘了 (double) 转义右括号。
(cl-ppcre:scan-to-strings "\[([a-zA-Z0-9_-]+)\]" "[has-instance]")
;; "[has-instance]" ;
;; #("has-instance")
对于 common lisp 的新手,您可以使用 quicklisp 导入 cl-ppcre
:
(load "~/quicklisp/setup.list") ;; adjust path to where you installed your quicklisp
(ql:quickload :cl-ppcre)