Неверное совпадение с регулярным выражением при использовании cl-ppcre?
Попытка разобрать следующий текстовый файл:
prefix1 prefix2 name1(
type1 name1,
type2 name2
);
со следующим регулярным выражением:\\s*prefix1\\s*prefix2\\s*(\\w[\\w\\d_]*).*\\(\\s*([^\\)]*\\))\\s*;\\s*
В результате я получаю следующие две группы (регистры):
"name1(
"
а также
"(
type1 name1,
type2 name2
)"
(здесь кавычки ограничивают строку, \n включены)
Я не могу понять, почему первая группа (\w[\w\d_]*)
соответствует следующему .*
часть. Более того, я не могу избавиться от ненужного хвоста!
В чем моя ошибка?
ДОБАВИТЬ: проанализированное регулярное выражение:
(cl-ppcre::parse-string "\\s*prefix1\\s*prefix2\\s*(\\w[\\w\\d_]*).*\\(\\s*([^\\)]*\\))\\s*;\\s*")
(:SEQUENCE (:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS) "prefix1"
(:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS) "prefix2"
(:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS)
(:REGISTER
(:SEQUENCE :WORD-CHAR-CLASS
(:GREEDY-REPETITION 0 NIL (:CHAR-CLASS :WORD-CHAR-CLASS :DIGIT-CLASS #\_))))
(:GREEDY-REPETITION 0 NIL :EVERYTHING) #\(
(:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS)
(:REGISTER
(:SEQUENCE (:GREEDY-REPETITION 0 NIL (:INVERTED-CHAR-CLASS #\))) #\)))
(:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS) #\;
(:GREEDY-REPETITION 0 NIL :WHITESPACE-CHAR-CLASS))
ДОБАВИТЬ 2: Полный источник:
;; Requirements:
;; cl-ppcre
(defparameter *name-and-parameters-list* (cl-ppcre::create-scanner "\\s*prefix1\\s*prefix2\\s*(\\w[\\w\\d_]*)\\s*\\(\\s*([^\\)]*\\))\\s*;\\s*"))
(defparameter *filename* "c:/pva/home/test.txt")
(defun read-txt-without-comments (file-name)
"Would epically fail in case the file format changes, because currently it expects
the \"/*\" and \"*/\" sequences to be on the separate line."
(let ((fstr (make-array '(0) :element-type 'base-char :fill-pointer 0 :adjustable t)))
(with-output-to-string (s fstr)
(let ((comment nil))
(with-open-file (input-stream file-name :direction :input)
(do ((line (read-line input-stream nil 'eof) (read-line input-stream nil 'eof)))
((eql line 'eof))
(multiple-value-bind (start-comment-from)
(cl-ppcre:scan ".*/\\*" line)
(multiple-value-bind (end-comment-from)
(cl-ppcre:scan ".*\\*/" line)
(if start-comment-from
(setf comment t))
(if (not comment)
(format s "~A~%" line))
(if end-comment-from
(setf comment nil))))))))
fstr))
(let* ((string (read-txt-without-comments "c:/pva/home/test.txt")))
(multiple-value-bind (a b c d) (cl-ppcre::scan *name-and-parameters-list* string)
(format t "~a ~a ~a ~a~%|~a|~%|~a|~%"
a b c d
(subseq string (svref c 0) (svref c 1))
(subseq string (svref d 0) (svref d 1)))))
ДОБАВИТЬ 3: Полный ввод:
prefix1 prefix2 name1(
type1 name1,
type2 name2
);
prefix1 prefix2 name2( type3 name1, type2 name2 );
1 ответ
Решение
Это работает для меня с недавним cl-ppcre
как вы и ожидали
(cl-ppcre:register-groups-bind (name argument)
("\\s*prefix1\\s*prefix2\\s*(\\w[\\w\\d_]*).*\\(\\s*([^\\)]*\\))\\s*;\\s*"
"prefix1 prefix2 name1(
type1 name1,
type2 name2
);" :sharedp t)
(list name argument))
("name1" "type1 name1,
type2 name2
)")
Может быть, показать немного больше кода?