2016-07-08 2 views
0

Следующий код из https://www.rosettacode.org/wiki/Tokenize_a_string#Common_Lisp разбивает строку запятыми и отправляет список.Как обрезать после разделения строки на список в Lisp

(defun comma-split (string) 
    (loop for start = 0 then (1+ finish) 
     for finish = (position #\, string :start start) 
     collecting (subseq string start finish) 
     until (null finish) 
) 
) 

Однако подстроки будут иметь пробелы вокруг них, если они находятся в исходной строке.

> (comma-split " a, b ,c , d , e") 
(" a" " b " "c " " d " " e") 

Как добавить функцию строковой обрезки, чтобы удалить эти пробелы здесь. Я не вижу строку, возвращаемую функцией.

Я пытался иметь локальную переменную, но она не работает:

(defun comma-split2 (string) 
(let* ((onestr "") 
    ) 
    (loop for start = 0 then (1+ finish) 
     for finish = (position #\, string :start start) 
     (onestr (subseq string start finish)) 
     (onestr (string-trim onestr)) 
     collecting onestr 
     until (null finish) 
) 
)) 

Ошибка на загрузке файла:

*** - LOOP: illegal syntax near (ONESTR (SUBSEQ STRING START FINISH)) in 
     (LOOP FOR START = 0 THEN (1+ FINISH) FOR FINISH = (POSITION #\, STRING :START START) (ONESTR (SUBSEQ STRING START FINISH)) 
     (ONESTR (STRING-TRIM ONESTR)) COLLECTING ONESTR UNTIL (NULL FINISH)) 
The following restarts are available: 

Даже обрезку outlist во второй функции не работает:

(defun comma-split2 (string) 
(let ((outlist (list)) 
    (setf outlist (comma-split string)) 
    (dolist (str outlist) 
     (push (string-trim str) outlist) 
    ) 
    (nreverse outlist) 
))) 

> (comma-split2 " a, b ,c , d , e") 

*** - LET: illegal variable specification (SETF OUTLIST (COMMA-SPLIT STRING)) 
The following restarts are available: 

ответ

3

COLLECTING -statement является то, что создает ЛИС т. Поэтому вам нужно позвонить в STRING-TRIM вокруг того, что собирается.

(defun comma-split (string) 
    (loop for start = 0 then (1+ finish) 
     for finish = (position #\, string :start start) 
     collecting (string-trim " " (subseq string start finish)) 
     until (null finish))) 

Вы не должны помещать закрывающие круглые скобки в свою собственную линию.

-1

Вы можете использовать метод string-trim. Например

(string-trim '(#\Space #\Tab #\Newline) " Test Test") => "Test Test" . 

Для получения дополнительной информации вы можете пойти here.

Надеюсь, это поможет! :)

+0

Я знаю об этом, но я пытаюсь включить его в саму функцию. Pl см. Мое редактирование выше. – rnso

1

Ваш код недействителен Синтаксис LOOP. Либо использовать простой синтаксис, который, как PROGN но петли, или вы используете LOOP ключевые слова, и в этом случае нужно, чтобы префикс заявления с DO:

(loop 
    for i in list 
    do 
    (print i) 
    (sleep 1)) 

Вы, вероятно, только нужно сделать:

(loop for start = 0 then (1+ finish) 
     for finish = (position #\, string :start start) 
     collect (string-trim " " 
          (subseq string 
            start 
            finish)) 
     until (null finish)) 

в качестве альтернативы, с регулярными выражениями (см http://weitz.de/cl-ppcre/):

(ppcre:split " *, *" string) 
+0

Как я могу использовать долист здесь? Я думал, что долист сделан для списков и должен быть самым простым в использовании здесь. – rnso

+0

'NIL' фактически является допустимой конечной позицией для' SUBSEQ' (это значение по умолчанию, означающее остальную часть строки). – jkiiski

+0

Вы не перебираете список, поэтому dolist не подходит. Долист просто привязывает символ к каждому элементу списка, вам нужно добавить свой собственный код для обработки и, возможно, собрать результат, что и делает LOOP. – coredump

1

Без надлежащего отступающего кода Lisp вы не получите очень далеко.

Не:

(defun foo (a) 
(let ((b) 
b 
)) 
) 

Написать

(defun foo (a) 
    (let (b) 
    b)) 

Дополнительно: пытаясь написать Lisp код без понимания Lisp синтаксис также не является хорошей идеей.

Попытка использования сложного языка путем случайного кода в Google, попытка случайного изменения кода, а затем публикация сообщений об ошибках в Stackoverflow не является очень перспективным подходом.

Читайте один или несколько основных лисповских книг:

Используйте лисповскую ссылка: Common Lisp Hyperspec

LOOP: незаконный синтаксис около

Читайте о LOOP, в первую очередь.

LET: нелегальный спецификация переменной

Вызванный отсутствие отступа и нарушение Лиспа синтаксиса. Проверьте синтаксис LET.

Как я могу добавить функцию строкового дифферента, чтобы удалить эти пробелы здесь

Как добавить функции на всех?

Учитывая это выражение:

(sin 3.0) 

Как добавить функцию для вычисления квадратного корня?

Решение:

(sqrt (sin 3.0)) 

Вы вызываете функцию на результат первого.

Простой как это. Зачем вам нужны дополнительные переменные?

Смежные вопросы